/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2008 Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
* AdobePatentID="B564"
* AdobePatentID="B565"
*
**************************************************************************/

if (typeof Kore == "undefined") {
	Kore = {};
};

BrowserHistory = {
	getURL: function() {}

};


Kore.browserNotSupportedURL = 'client/not_supported.html';

/**
 * This function returns the current server details to be 
 * displayed in the Flex About dialog
 */
Kore.getAboutDetails = function() {
	var retObj = {
		path: iceServerRoot,
		buildVersion: "1.6.0.1053b",
		buildNumber: "1053",
		buildDate: "2009-07-13 16:26:48"
	};

	return retObj;
};

/**
 * Defines the list of supported browser engines, browsers and their min/max versions
 * 
 * Syntax: {os:version, os:version}
 *  where os can be one of "windows", "mac", "linux" or "unix".
 * Version is an object, with syntax {"supported":int constant, flash:string, "from":number, "to":number},
 *  meaning any version in the "from" to "to" range, inclusively.
 * The "to" declaration is optional, meaning there's no upper limit version check.
 * The "flash" declaration specifies the minimim required Flash player version
 *  in the "major,minor,revision" format.
 * The "supported" declaration specifies the level of the support for the browser
 *  can be one of the following values:
 *    0: browser supported
 *    1: browser is not supported, user can continue to ICE
 *    2: browser is not in the list of accepted browsers, user can continue to ICE
 */
Kore.browserSupport = {
	SUPPORTED: 0,
	MAYBE: 1,
	NOTSUPPORTED: 2
};

Kore.acceptedBrowsers = {
	"mozilla": {
		"Mozilla Firefox": {
			"windows": {supported: Kore.browserSupport.SUPPORTED, flash: "10,0,12", from: 3},
			"mac": {supported: Kore.browserSupport.SUPPORTED, flash: "10,0,12", from: 3},
			"linux": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 3},
			"unix": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 3}
		}
	},
	"ie": {
		"Internet Explorer": {
			"windows": {supported: Kore.browserSupport.SUPPORTED, flash: "10,0,12", from: 6}
		}
	},
	"safari": {
		"Apple Safari": {
			"mac": {supported: Kore.browserSupport.SUPPORTED, flash: "10,0,12", from: 3.1},
			"windows": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 3.1}
		},
		"Adobe AIR": {
			"windows": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 1.5},
			"mac": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 1.5},
			"linux": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 1.5},
			"unix": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 1.5}
		},
		"Google Chrome": {
			"windows": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 0.4},
			"mac": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 0.4},
			"linux": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 0.4},
			"unix": {supported: Kore.browserSupport.MAYBE, flash: "10,0,12", from: 0.4}
		}
	}
};

/**
 * This call constructs the Kore.is object used all over the application to get 
 * the current browser and its version.
 */
Kore.is = new (function () {
	var b = navigator.appName.toString();
	var up = navigator.platform.toString();
	var ua = navigator.userAgent.toString();

	this.mozilla = this.ie = this.opera = this.safari = false;
	var r = false;
	var re_opera = /Opera.([0-9\.]*)/i;
	var re_msie = /MSIE.([0-9\.]*)/i;
	var re_firefox = /(?:Firefox|Minefield|GranParadiso)\/([\d\.]*)/i;
	var re_adobeair = /AdobeAIR\/([\d\.]*)/i;
	var re_safari = /Safari\/([\d\.]*)/i;
	var re_chrome = /Chrome\/([\d\.]*)/i;

	this.Browser = "unknown";
	this.Flavor = "unknown";
	if (ua.match(re_opera)) {
		r = ua.match(re_opera);
		this.Browser = "opera";
		this.Flavor = "opera";
		this.opera = true;
		this.version = parseFloat(r[1]);
	} else if (ua.match(re_msie)) {
		r = ua.match(re_msie);
		this.ie = true;
		this.Browser = "ie";
		this.version = parseFloat(r[1]);
		this.Flavor = "Internet Explorer";
	} else if (ua.match(re_adobeair)) {
		r = ua.match(re_adobeair);
		this.safari = true;
		this.Browser = "safari";
		this.Flavor = "Adobe AIR";
		this.version = parseFloat(r[1]);
	} else if (ua.match(re_chrome)) {
		r = ua.match(re_chrome);
		this.safari = true;
		this.Browser = "safari";
		this.Flavor = "Google Chrome";
		this.version = parseFloat(r[1]);
	} else if (ua.match(re_safari)) {
		this.safari = true;
		this.Browser = "safari";
		this.Flavor = "Apple Safari";
		r = ua.match(/Version\/([\d\.]*)/);
		if (r) {
			this.version = parseFloat(r[1]);
		} else {
			this.version = 0;
		}
	} else if (ua.match(re_firefox)) {
		r = ua.match(re_firefox);
		this.mozilla = true;
		this.Browser = "mozilla";
		this.Flavor = "Mozilla Firefox";
		this.version = parseFloat(r[1]);
	}
	this.windows = this.mac = this.linux = false;

	this.Platform = ua.match(/windows/i) ? "windows" :
					(ua.match(/linux/i) ? "linux" :
					(ua.match(/mac/i) ? "mac" :
					ua.match(/unix/i)? "unix" : "unknown"));
	this[this.Platform] = true;
	this.v = this.version;
	return this;
})();

/**
 * Detects and stores the level of support from the browser and flash 
 * sets the Kore.environment structure:
 *    specified: boolean, browser is recognised in the Kore.acceptedBrowsers structure
 *    browser.supported: int, one of the Kore.browserSupport values
 *    browser.isVersionSupported: boolean, version is supported
 *    flash.minVersion: String, the min flash version required for the detected browser
 *                     (set in the Kore.acceptedBrowsers structure)
 *    flash.installedVersion: String, the installed flash version
 *    flash.isInstalled: boolean, true if flash is installed
 *    flash.isValid: boolean, true when flash.installedVersion gte flash.minVersion
 */
Kore.detectEnvironment = function() {
	var is = Kore.is;
	Kore.environment = {
		specified: false,
		browser: {
			supported: Kore.browserSupport.NOTSUPPORTED,
			isVersionSupported: false
		},
		//default required Flash Version is the latest available version
		//this may be set for each browser flavor in the Kore.acceptedBrowsers structure
		flash: {
			minVersion: "0,0,0",
			installedVersion: "0,0,0",
			isInstalled: false,
			isValid: false
		}
	};
	// Browser Type
	var flavors = Kore.acceptedBrowsers[is.Browser];
	if (typeof flavors != 'undefined') {
		var operatingSystems = flavors[is.Flavor];
		if (operatingSystems != undefined) {
			// Operating System
			var details = operatingSystems[is.Platform];
			if (details != undefined) {
				Kore.environment.specified = true;
				//check browser support: supported or maybe supported
				if (
					details.supported == Kore.browserSupport.SUPPORTED
						||
					details.supported == Kore.browserSupport.MAYBE
				) {
					var versionSupported = true;
					if (versionSupported && details.from != undefined) {
						versionSupported = details.from <= is.version;
					}
					if (versionSupported && details.to != undefined) {
						versionSupported = is.version <= details.to;
					}
					Kore.environment.browser.supported = details.supported;
					Kore.environment.browser.isVersionSupported = versionSupported;
					Kore.environment.flash.minVersion = details.flash;
				}
			}
		}
	}

	Kore.environment.flash.installedVersion = Kore.FlashHelper.getFlashPlayerVersion();
	Kore.environment.flash.isInstalled = Kore.environment.flash.installedVersion != "0,0,0";
	Kore.environment.flash.isValid = Kore.versionCompare(Kore.environment.flash.installedVersion, Kore.environment.flash.minVersion) >= 0;
};

/**
 * This function compares two text versions (x.x.x format)
 *
 * @param ver1, ver2 - String - product version
 * @return numeric 
 *    0 if ver1 == ver2
 *    1 if ver1 > ver2
 *   -1 if ver1 < ver2
 */
Kore.versionCompare = function (ver1, ver2) {
	var re = /[\.\,]/gi;

	var arr1 = ver1.split(re);
	var arr2 = ver2.split(re);

	var cmp = 0;
	var ix = 0;

	while (cmp == 0 && (arr1.length > ix || arr2.length > ix)) {
		if (((arr1.length <= ix) && (arr2.length > ix)) || (parseInt(arr1[ix]) < parseInt(arr2[ix]))) {
			cmp = -1;
		} else if (((arr2.length <= ix) && (arr1.length > ix)) || (parseInt(arr1[ix]) > parseInt(arr2[ix]))) {
			cmp = 1;
		}
		ix++;
	}
	return cmp;
};

/**
 * This function is called after user presses login shortcut (usually CTRL+E) 
 * and the current environment is valid.
 */
Kore.environmentValidCallback = function() {
	if (typeof isPortal == "undefined") {
		Kore.loadCSSFile(iceServerRoot + 'client/css/loader.css');
		Kore.addIFR();
		Kore.showLoadingIndicator();
		if (typeof preBundled == "undefined") {
			var brow = Kore.is.ie ? ("ie" + Kore.is.version) : Kore.is.safari ? "safari" : Kore.is.mozilla ? "ff" : "NA";
			Kore.loadCSSFile(iceServerRoot + 'client/bundles/ice_' + brow + '.css');
			Kore.loadCSSFile(iceServerRoot + 'client/bundles/ice_' + brow + '_edit.css', 'cssEdit');
			Kore.loadJsFile(iceServerRoot + 'client/bundles/ice_' + brow + '.js', function() {
				setTimeout(function(){ICE.start();}, 0);
			});
		} else {
			bundleCSSIncludes();
			setTimeout(function(){ICE.start();}, 0);
		}
	} else {
		Kore.ICEClientId = "portal";
		Kore.FlashHelper.runContent(
			"document", document,
			"src", "assets/swf/portal",
			"width", "100%",
			"height", "100%",
			"align", "middle",
			"id", Kore.ICEClientId,
			"quality", "high",
			"bgcolor", "white",
			"name", Kore.ICEClientId,
			"allowScriptAccess","sameDomain",
			"allowFullScreen","true",
			"type", "application/x-shockwave-flash",
			"pluginspage", "http://www.adobe.com/go/getflashplayer"
		);
	}
};


/**
 * This function decides if the includes files from the user's website are 
 *  compatible with current server or not.
 *
 * @return Boolean True if the server and includes files are compatible, false otherwise
 */
Kore.isServerCompatibleWithIncludesFolder = function() {
	// TODO: in the future write this function that will analyze the version of the includes files from the user's website and
	//       decide whether or not current server is compatible with them or not.
	//       This function should use the variable named 'iceFilesVersion' (defined in the includes/ice/ide.html file)
	return true;
};

/**
 * This function will do the right thing (display an alert, redirect to a page, etc.) in case the current includes
 * files deployed on the user's website are incompatible with current server version.
 */
Kore.includesFilesNotCompatibleCallback = function() {
	// TODO: implement this function that will do the right thing (display an alert, redirect to a page, etc.) in case
	//       the current includes files deployed on the user's website are incompatible with current server version
};

/**
 * Called if the browser is obsolete and there were errors while attempting to 
 *  show the invalid environment error messages
 */
Kore.browserNotSupportedCallback = function() {
	//redirect to browser not supported page from the ICE server
	window.location = iceServerRoot + Kore.browserNotSupportedURL;
};

/**
 * Called when the browser is not supported
 *  or flash is not installed or an older version is installed
 */
Kore.environmentInvalidCallback = function() {
	var sections = [];
	var m = Kore.errorMessages;

	var showBrowserNotSupported = Kore.environment.browser.supported == Kore.browserSupport.MAYBE
									||
								Kore.environment.browser.supported == Kore.browserSupport.NOTSUPPORTED;

	var showBrowserVersionNotSupported = !showBrowserNotSupported
											&&
										!Kore.environment.browser.isVersionSupported;
	var showDialogButtons = false;
	var showContinueButton = true;
	var showCancelButton = typeof isPortal == 'undefined';

	if (showBrowserNotSupported || showBrowserVersionNotSupported) {
		var browserMessage = '';
		//browser not supported or browser version not supported
		//say not supported
		if (showBrowserVersionNotSupported) {
			browserMessage += m.browserVersionNotSupported;
		} else if (showBrowserNotSupported) {
			browserMessage += m.browserNotSupported;
		}

		//show continue warning
		browserMessage += m.continueWarning;

		//say there are supported browsers
		browserMessage += m.browsersSupportedMessage;

		if (typeof m.osBrowsersSupportedList[Kore.is.Platform] != 'undefined') {
			//the current OS is supported (there are supported browsers for this OS)
			//show browser list only for this OS, don't show the OS name
			var struct = m.osBrowsersSupportedList[Kore.is.Platform];
			browserMessage += struct.browsers.join('');
		} else {
			//show browser list for all supported OSs
			var struct = m.osBrowsersSupportedList['windows']
			browserMessage += struct.title + struct.browsers.join('');
			struct = m.osBrowsersSupportedList['mac'];
			browserMessage += struct.title + struct.browsers.join('');
		}

		sections.push(browserMessage);

		//display Continue&Cancel buttons
		showDialogButtons = true;
	}

	if (!Kore.environment.specified) {
		//browser/os unknown
		showDialogButtons = true;
	} else {
		if (Kore.environment.browser.supported == Kore.browserSupport.SUPPORTED && Kore.environment.browser.isVersionSupported) {
			//browser OK
			//if Flash not OK, should not be able to continue
			showContinueButton = false;
		}

		var flashMessage = '';
		if (!Kore.environment.flash.isInstalled) {
			//any browser, no Flash, require Kore.environment.flash.minVersion
			flashMessage = m.flashSectionStart + m.noFlashRequireMinVersion.replace(/@@paramRequiredFlashVersion@@/gi, Kore.environment.flash.minVersion) + m.flashSectionEnd;
			showDialogButtons = true;
		} else if (!Kore.environment.flash.isValid) {
			//any browser, older Flash, require Kore.environment.flash.minVersion
			var str = m.withFlashRequireMinVersion;
			str = str.replace(/@@paramRequiredFlashVersion@@/gi, Kore.environment.flash.minVersion);
			str = str.replace(/@@paramInstalledFlashVersion@@/gi, Kore.environment.flash.installedVersion);
			flashMessage  = m.flashSectionStart + str + m.flashSectionEnd;
			showDialogButtons = true;
		}
		if (flashMessage) {
			sections.push(flashMessage);
		}
	}

	if (showDialogButtons && (showContinueButton || showCancelButton)) {
		var str = m.dialogButtonsStart;
		if (showContinueButton) {
			str += m.dialogButtonContinue;
		}
		if (showCancelButton) {
			str += '&nbsp;&nbsp;&nbsp;&nbsp;' + m.dialogButtonCancel;
		}
		str += m.dialogButtonsEnd;
		sections.push(str);
	}

	Kore.showMessageDialog(sections.join(m.sectionSeparator));
};

/**
 * Called when the user has a not supported browser
 *  and he doesn't want to continue to ICE
 */
Kore.cancelMaybeSupported = function() {
	var page = Kore.getPageLocation();
	window.location.href = "../../" + page;
};

/**
 * Called when the environment is not valid and the user accepts to continue to ICE
 */
Kore.continueMaybeSupported = function() {
	//remember user choice in a session cookie
	document.cookie = 'skipicebrowsercheck=1';
	Kore.hideMessageDialog();
	Kore.environmentValidCallback();
};

/**
 * Dynamic JavaScript file inclusion using SCRIPT tag
 *
 * @param String src The source URL
 * @param Function callback The callback to call when loading completes (optional)
 * @param String id The ID of the SCRIPT tag (optional)
 */
Kore.loadJsFile = function (src, callback, id) {
	var head=document.getElementsByTagName('HEAD')[0];
	callback = callback || function(){};
	var script = document.createElement('SCRIPT');
	script.type = 'text/javascript';
	if (typeof(id) != "undefined") {
		script.id = id;
	}
	script.onload = function() {
		callback();
	}
	script.onreadystatechange = function() {
		if (typeof this.jsloaded == 'undefined' && (this.readyState == 'complete' || this.readyState == 'loaded')){
			this.jsloaded = true;
			callback();
		}
	};
	script.src = src;
	head.appendChild(script);
};

/**
 * Dynamic CSS file inclusion using LINK type="text/css" tag
 *
 * @param String src The source URL
 * @param String id The ID of the LINK tag (optional)
 */
Kore.loadCSSFile = function (src, id) {
	var lnk = document.createElement('LINK');
	lnk.rel = "stylesheet";
	lnk.type = "text/css";
	if (typeof(id) != "undefined") {
		lnk.id = id;
	}
	var head=document.getElementsByTagName('HEAD')[0];
	head.appendChild(lnk);
	lnk.href = src;
};

/**
 * This function adds the IFRAME that contains the initial user page.
 * Called after the environment was validated.
 */
Kore.addIFR = function() {
	var div = document.createElement("DIV");
 	div.id = "iframe_container";
 	document.body.appendChild(div);

	var iframe = document.createElement("IFRAME");
	iframe.id = "page_container";
	iframe.name = "page_container";
	
	/**
	 * Bug: #2315636 On slow connection when CTRL+E is pressed an empty
	 * rectangle is rendered before ICE
	 *
	 * Fix is to temporarly hide the iframe until the width is set
	 * @see ICE.finalInit in init.js
	 */
	iframe.style.visibility = 'hidden';
	
	if (Kore.is.ie && window.location.protocol == 'https:') {
		//avoid IE secured and nonsecure items warning on https
		iframe.src = 'javascript:""';
	}
	div.appendChild(iframe);

	var page = Kore.getPageLocation();
	iframe.contentWindow.location.href = "../../" + page;
};

/**
 * This function calls the decodeURI function on the given string and takes care of possible wrong escaped '%' characters
 *
 * @param String str The string to apply decodeURI to
 * @return String The string after decode operation
 */
Kore.decodeURI = function(str) {
	return Kore.customDecodeURI("decodeURI", str);
};

/**
 * This function calls the decodeURIComponent function on the given string and takes care of possible wrong escaped '%' characters
 *
 * @param String str The string to apply decodeURIComponent to
 * @return String The string after decode operation
 */
Kore.decodeURIComponent = function(str) {
	return Kore.customDecodeURI("decodeURIComponent", str);
};

/**
 * This function calls either the decodeURI or decodeURIComponent method on the given string and returns the result. It takes
 * care of the possible unescaped (orphaned) '%' chracters and escapes them properly, so the decodeURI/decodeURIComponent functions
 * will not throw malformed URI sequence exceptions.
 *
 * @param String method The method to apply. Supported values are 'decodeURI' and 'decodeURIComponent'
 * @param String str The string to apply the method to
 * @return String The given str having the given method applied to
 */
Kore.customDecodeURI = function(method, str) {
	var newStr = str;

	try {
		if (method == "decodeURI") {
			newStr = decodeURI(newStr);
		} else if (method == "decodeURIComponent") {
			newStr = decodeURIComponent(newStr);
		}
	} catch (err) {
		newStr = newStr.replace(/\%(?=[0-9a-f][^0-9a-f]|[^0-9a-f]|[0-9a-f]$|$)/gi, "%25"); // %25 is the encoded version of '%' char
		try {
			if (method == "decodeURI") {
				newStr = decodeURI(newStr);
			} else if (method == "decodeURIComponent") {
				newStr = decodeURIComponent(newStr);
			}
		} catch(e) {
			// Normally you should not get here. If you see this error message, please report a bug to be fixed.
			alert(err);
		}
	}

	return newStr;
};

/**
 * This function returns the page name without search parameters and/or anchors
 *
 * @param String page The page URL for which we need to get the page name
 * @return String The page name with any search paramsters and/or anchors removed
 */
Kore.getPageNameOnly = function(page) {
	var newPage = page.replace(/\?.*$/gi, "");
	newPage = newPage.replace(/\#.*$/gi, "");
	return newPage;
};

/**
 * This function returns the published name of the given page by preserving any search paramsters and/or anchors
 *
 * @param String page The page URL for which we need to get the published name
 * @return String The published page name of the given page with any search paramsters and/or anchors preserved
 */
Kore.getPublishedPageName = function(page) {
	var ending = /_draft((?:\.[\w\d]+)?(?:\?.*)?(?:\#.*)?)$/;
	return page.replace(ending, "$1");
};

/**
 * This function returns the draft name of the given page by preserving any search paramsters and/or anchors
 *
 * @param String page The page URL for which we need to get the draft name
 * @return String The draft page name of the given page with any search paramsters and/or anchors preserved
 */
Kore.getDraftPageName = function(page) {
	var ending = /((?:\.[\w\d]+)?(?:\?.*)?(?:\#.*)?)$/;
	return page.replace(ending, "_draft$1");
};

/**
 * This function ensures that the given string is properly encoded.
 * It is used because some browsers return only
 * partially encoded the window.location.
 *
 * @param String str The string to check and repair
 * @return String The given string properly encoded
 */
Kore.ensureProperlyEncodedStr = function(str) {
	// Function Kore.decodeURIComponent() is defined in loader.js. We are using Kore.decodeURIComponent() function
	// to handle the case when the URL contains "orphaned" percent signs - those cases may throw an malformed URI
	// component exception.
	return encodeURIComponent(Kore.decodeURIComponent(str));
};

/**
 * This function ...
 *
 * @param String url The URL to ensure that is valid
 * @return String The given URL having all special chars properly encoded
 */
Kore.getValidURL = function(url) {
	var matches = url.match(/^(\w+\:\/\/)?([^\?\#\/\:]+)?(\:\d+)?([^\?\#]*)?(?:\?(.*?))?(?:\#(.*?))?$/);

	var PROTOCOL_INDEX = 1;
	var DOMAIN_INDEX = 2;
	var PORT_INDEX = 3;
	var PATH_DOMAIN_INDEX = 4;
	var SEARCH_INDEX = 5;
	var HASH_INDEX = 6;

	if (!matches) {
		alert("Invalid use. Please provide valid URLs.\nReceived: " + url);
		throw("Error: Invalid URL.");
	}

	// Make sure the domain is properly encoded
	if (matches[DOMAIN_INDEX]) {
		matches[DOMAIN_INDEX] = Kore.ensureProperlyEncodedStr(matches[DOMAIN_INDEX]);
	}

	// If we have a path, then make sure each block separated by '/' should be properly encoded
	if (matches[PATH_DOMAIN_INDEX]) {
		var pathParts = matches[PATH_DOMAIN_INDEX].split("/");
		for (var i=0; i<pathParts.length; i++) {
			pathParts[i] = Kore.ensureProperlyEncodedStr(pathParts[i]);
		}
		matches[PATH_DOMAIN_INDEX] = pathParts.join("/");
	}

	// Make sure all special chars in SEARCH are properly encoded
	if (matches[SEARCH_INDEX]) {
		matches[SEARCH_INDEX] = "?" + Kore.ensureProperlyEncodedStr(matches[SEARCH_INDEX]);
	}

	// Make sure all special chars in HASH are properly encoded
	if (matches[HASH_INDEX]) {
		matches[HASH_INDEX] = "#" + Kore.ensureProperlyEncodedStr(matches[HASH_INDEX]);
	}

	var fixedLink = "";

	for (var i=1; i<matches.length; i++) {
		if (matches[i]) {
			fixedLink += matches[i];
		}
	}

	return fixedLink;
};

/**
 * Returns the current page, relative to initial site root. The value is extracted form the hash value
 * of the current URL (which looks similar to http://[user_website_root]/inclues/ice/ide.html#page=folder1/folder2/page.html)
 *
 * @return String The page the user is viewing/editing out of special URL used by InContext Editing
 */
Kore.getPageLocation = function() {
	var loca = "";

	try {
		loca = Kore.HashManager.getParam('page');
		if (loca == undefined) {
			loca = "";
			Kore.HashManager.setParam('page', '');
		}
		// Normally both IE and Safari behave the same - they return both exactly what is in the hash of the page. But since Safari 
		// starts with a "handicap" form ide.html (it is one level "less" encoded") we will not do besides decodeURIComponent also a
		// getValidURL to make sure special chars are correctly handled.
		// FF applies a decodeURIComponent automatically when reading the window.location.hash
		// => therefore we will need to make a call to decodeURIComponent only if not Mozilla.
		if (!Kore.is.mozilla) {
			loca = Kore.decodeURIComponent(loca);
		}
		if (Kore.is.safari) {
			loca = Kore.getValidURL(loca);
		}
		loca = Kore.getPublishedPageName(loca);
	} catch(e) {}

	return loca;
};

/**
 * Normally both IE and Safari behave the same - they return both exactly what is in the hash of the page. But since Safari 
 * starts with a "handicap" form ide.html (it is one level "less" encoded") we will not do besides decodeURIComponent also a
 * getValidURL to make sure special chars are correctly handled.
 * FF applies a decodeURIComponent automatically when reading the window.location.hash
 * => therefore we will need to make a call to decodeURIComponent only if not Mozilla.
 */
Kore.decodeHash = function(hash) {
	if (!Kore.is.mozilla) {
		hash = Kore.decodeURIComponent(hash);
	}
	if (Kore.is.safari) {
		hash = Kore.getValidURL(hash);
	}
	return hash;
};

/**
 * Adds a simple loading indicator created by JS
 */
Kore.showLoadingIndicator = function() {
	var tmp = document.createElement('div');
	tmp.innerHTML = '<div id="primitive_loading_indicator"><div></div></div>';
	document.body.appendChild(tmp.firstChild);
};

/**
 * Flash Player Version Detection - based on Rev 1.5
 * Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
 */
Kore.FlashHelper = {};

/**
 * Returns the Flash player version installed or "0,0,0" if not installed
 */
Kore.FlashHelper.getFlashPlayerVersion = function() {
	var version = "0,0,0";

	if (navigator.plugins && navigator.plugins.length > 0) {
		var type = 'application/x-shockwave-flash';
		var mimeTypes = navigator.mimeTypes;
		if (mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin && mimeTypes[type].enabledPlugin.description) {
			var versionString = mimeTypes[type].enabledPlugin.description;
			var descParts = versionString.split(/ +/);
			var majorMinor = descParts[2].split(/\./);
			var revisionStr = descParts[3];

			version = parseInt(majorMinor[0], 10) + ",";
			version += parseInt(majorMinor[1], 10) + ","
			version += parseInt(revisionStr.replace(/[a-zA-Z]/g, ""), 10);
		}
	} else if (Kore.is.ie) {
		var flash = null;
		try {
			flash = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
		} catch(err) {}

		if (flash) {
			var found = null;
			//find the greatest installed version of the Flash component
			for (var i = 2; i < 100; i++) {
				try {
					flash = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + i);
				} catch (err) {
					flash = null;
				}
				if (flash == null) {
					if (found) {
						break;
					}
				} else {
					found = flash;
				}
			}
			if (found) {
				var versionString = "";
				try {
					versionString = found.GetVariable("$version");
				} catch (err) {/*may fail for certain Flash versions*/}

				if (versionString) {
					var versionArray = versionString.split(",");
					version = parseInt(versionArray[0].split(' ')[1], 10) + ",";
					version += parseInt(versionArray[1], 10) + ",";
					version += parseInt(versionArray[2], 10);
				}
			}
		}
	}

	return version;
};

Kore.FlashHelper.addExtension = function(src, ext) {
  if (src.indexOf('?') != -1) {
    return src.replace(/\?/, ext+'?');
	} else {
    return src + ext;
	}
};

Kore.FlashHelper.addFlashHTML = function(div, doc, objAttrs, params, embedAttrs) {
	var str = "";

	if ( (Kore.is.ie && Kore.is.windows) || Kore.is.safari) {
		str += '<object ';
		for (var i in objAttrs)str += i + '="' + objAttrs[i] + '" ';
		str += ">";
		for (var i in params)str += '<param name="' + i + '" value="' + params[i] + '" />';
		str += '</object>';
		div.innerHTML = str;
	} else {
		div.innerHTML = str;
		var flashMovieTag = doc.createElement("EMBED");
		for (var i in embedAttrs) {
			flashMovieTag.setAttribute(i, embedAttrs[i]);
		}
		div.appendChild(flashMovieTag);
	}
	return true;
};

Kore.FlashHelper.generateobj = function(doc, target, objAttrs, params, embedAttrs, id) {
	if (!target) {
		var div = doc.createElement('DIV');
		doc.body.appendChild(div);
	} else {
		var div = target;
	}

	div.id = id || "div_flex_top";
	div.style.position = "absolute";
	if (Kore.is.safari) {
		//Safari displays 4 pixels after the OBJECT, EMBED, IMG tag inside XHTML 1.0 Strict pages
		//causing the vertical scrollbars to allways be displayed
		div.style.lineHeight = "0";
	}
	div.style.left = "0";
	div.style.top = "0";
	div.style.height = "100%";
	div.style.width = "100%";
	div.style.zIndex = "10000";
	return Kore.FlashHelper.addFlashHTML(div, doc, objAttrs, params, embedAttrs);
};

Kore.FlashHelper.runContent = function(){
	var version = Kore.getAboutDetails().buildNumber;
	var ret = Kore.FlashHelper.getArgs(arguments, ".swf?version=" + version, "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash");
	return Kore.FlashHelper.generateobj(ret.document, ret.target, ret.objAttrs, ret.params, ret.embedAttrs, ret.div_id);
};

Kore.FlashHelper.getArgs = function(args, ext, srcParamName, classid, mimeType){
	var ret = new Object();
	ret.embedAttrs = new Object();
	ret.params = new Object();
	ret.objAttrs = new Object();
	ret.document = null;
	ret.target = null;
	for (var i=0; i < args.length; i=i+2){
		var currArg = args[i].toLowerCase();
		switch (currArg){
			case "div_id":
			case "document":
			case "target":
				ret[args[i]] = args[i+1];break;
			case "pluginspage":ret.embedAttrs[args[i]] = args[i+1];break;
			case "src":case "movie":args[i+1] = Kore.FlashHelper.addExtension(args[i+1], ext);ret.embedAttrs["src"] = args[i+1];ret.params[srcParamName] = args[i+1];break;
			case "type":ret.objAttrs[args[i]] = args[i+1];break;
			case "id":case "width":case "height":case "name":ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];break;
			default:ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
		}
	}
	ret.objAttrs["classid"] = classid;
	if (mimeType) ret.embedAttrs["type"] = mimeType;
	return ret;
};

//Add ICE favicon
try {
	var link = document.createElement("LINK");
	link.rel = "shortcut icon";
	link.type = "image/x-icon";
	link.href = iceServerRoot + "favicon.ico";
	document.getElementsByTagName("HEAD")[0].appendChild(link);
}catch(err){};

/**
 * Strings used to build message dialogs displayed when the environment is invalid:
 *  browserNotSupported - browser not supported, user may continue to ICE
 *  noFlashRequireMinVersion - Flash Player not installed, require specified version
 *  withFlashRequireMinVersion - Flash Player is installed, require specified version
 */
Kore.errorMessages = {
	sectionSeparator: '<img src="' + iceServerRoot + 'client/images/border1.gif" width="100%" height="3" vspace="15" hspace="0"/>'
	, dialogStart: '<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%"><tr><td>\
		<img src="' + iceServerRoot + 'client/images/logo_name.gif" alt="Adobe Systems, Inc." />\
		<br /><img src="' + iceServerRoot + 'client/images/border1.gif" width="100%" height="3" vspace="0" hspace="0"/>\
		</td></tr>\
		<tr height="100%"><td align="center">\
		<table width="470" border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse;border-style:solid;border-width:1px;border-color:#404040 #000000 #000000 #404040;"><tr><td>\
		<table width="100%" border="1" cellspacing="0" cellpadding="15" height="100%" style="border-collapse:collapse;border:1px solid #5F5F5F;"><tr><td align="left">'
	, dialogEnd: '</td></tr></table></td></tr></table></td></tr></table>'
	, dialogButtonsStart: '<div align="right">'
	, dialogButtonsEnd: '</div>'
	, dialogButtonContinue: '<a href="" onclick="Kore.continueMaybeSupported();return false;">Continue</a>'
	, dialogButtonCancel: '<a href="" onclick="Kore.cancelMaybeSupported();return false;">Cancel</a>'
	, flashSectionStart: '<table cellpadding="0" cellspacing="0" border="0" width="100%"><tr><td>'
	, flashSectionEnd: '<div><a href="http://www.adobe.com/go/getflash/">Install Adobe Flash Player</a></div></td></tr></table>'
	, browserNotSupported: '<h4>We are sorry, your browser is not supported by Adobe InContext Editing.</h4>'
	, browserVersionNotSupported: '<h4>We are sorry, your browser version is not supported by Adobe InContext Editing.</h4>'
	, continueWarning: '<p>Even so you can choose to continue, but with the risk to encounter errors and dysfunctionalities.</p>'
	, browsersSupportedMessage: '<p>Alternatively, you can download one of the supported browsers, listed below:</p>'
	, osBrowsersSupportedList: {
		windows: {
			title: '<h4>On Windows</h4>'
			, browsers: [
				'<div>Download <a href="http://www.mozilla.com/firefox/">Mozilla Firefox 3 or higher</a></div>'
				, '<div>Download <a href="http://www.microsoft.com/windows/Internet-explorer/default.aspx">Internet Explorer 6 or higher</a></div>'
			]
		}
		, mac: {
			title:'<h4>On Mac</h4>'
			, browsers: [
				'<div>Download <a href="http://www.apple.com/safari/download/">Safari 3.1 or higher</a></div>'
				, '<div>Download <a href="http://www.mozilla.com/firefox/">Mozilla Firefox 3 or higher</a></div>'
			]
		}
	}
	, noFlashRequireMinVersion: '\
		<p>Adobe Flash Player is not installed.</p>\
		<p>Adobe InContext Editing requires Adobe Flash Player version @@paramRequiredFlashVersion@@ or higher.</p>'
	, withFlashRequireMinVersion: '\
		<p>You have Adobe Flash Player version @@paramInstalledFlashVersion@@ installed.</p>\
		<p>Adobe InContext Editing requires Adobe Flash Player version @@paramRequiredFlashVersion@@ or higher.</p>'
};

//Kore.messageDialogDiv is a DIV used to display messages
Kore.messageDialogDiv = null;

/**
 * Display the specified message in a dialog using a dynamically created DIV element.
 * 
 * @param message String the message to be shown to the user
 */
Kore.showMessageDialog = function(message) {
	Kore.hideMessageDialog();
	try {
		//using JavaScript to style the BODY element
		document.body.bgColor = "#484848";
		document.body.text = "#FFFFFF";
		document.body.link = "#B6D13C";
		document.body.vLink = "#B6D13C";
		document.body.style.fontFamily = "Arial, Helvetica, sans-serif";

		Kore.messageDialogDiv = document.createElement("DIV");
		Kore.messageDialogDiv.id = "message_dialog";
		document.body.appendChild(Kore.messageDialogDiv);
		Kore.messageDialogDiv.innerHTML = Kore.errorMessages.dialogStart + message + Kore.errorMessages.dialogEnd;
	} catch(err) {
		//older JavaScript may not support some language features
		//hard redirect to the static error page from the ICE server
		Kore.browserNotSupportedCallback();
	}
};

/**
 * Removes the existing message dialog DIV and the BODY styling
 */
Kore.hideMessageDialog = function() {
	if (Kore.messageDialogDiv) {
		Kore.messageDialogDiv.parentNode.removeChild(Kore.messageDialogDiv);
		Kore.messageDialogDiv = null;

		document.body.bgColor = "";
		document.body.text = "";
		document.body.link = "";
		document.body.vLink = "";
		document.body.style.fontFamily = "";
	}
};

Kore.HashManager = {
    'getParams' : function() {
    	var browserHash = window.location.hash;
    	if (browserHash == null || browserHash == undefined || browserHash == "") browserHash = "#";
    	var hash = window.location.hash.substr(1);
    	var pairs = hash.split('&');
    	if (pairs == null || pairs == undefined) pairs = new Array();
    	var result = {};
    	for (var i = 0; i < pairs.length; i++) {
    		var match = pairs[i].match(/([^=]+)=(.*)/);
    		if (match != null) {
				// Normally both IE and Safari behave the same - they return both exactly what is in the hash of the page. But since Safari 
				// starts with a "handicap" form ide.html (it is one level "less" encoded") we will not do besides decodeURIComponent also a
				// getValidURL to make sure special chars are correctly handled.
				// FF applies a decodeURIComponent automatically when reading the window.location.hash
				// => therefore we will need to make a call to decodeURIComponent only if not Mozilla.
				var name = match[1];
				var value = match[2];
				if (!Kore.is.mozilla) {
					name = Kore.decodeURIComponent(name);
					value = Kore.decodeURIComponent(value);
				}
	    		result[name] = value;
    		}
    	}
    	return result;
    },
    'setParams' : function(params) {
    	var hash = "";
    	var sep = '';
    	for (var name in params) {
    		if (params[name] != null && params[name] != undefined) {
    			hash += sep + encodeURIComponent(name) + '=' + encodeURIComponent(params[name]);
    			sep = '&';
    		}
    	}
    	window.location.hash = hash;
    },
	'getParam' : function(name) {
		return this.getParams()[name];
	},
	'setParam' : function(name, value) {
		var params = this.getParams();
		params[name] = value;
		this.setParams(params);
	}
};

/**
 * Call the appropriate callback depending on the environment:
 *  deployed includes folder is compatible or not with the current ICE server
 *  browser is not supported or browser version not supported
 *  flash not instaled or smaller version than required
 *  requirements passed
 */
Kore.validateEnvironment = function() {
	Kore.detectEnvironment();
	if (!Kore.isServerCompatibleWithIncludesFolder()) {
		Kore.includesFilesNotCompatibleCallback();
	} else {
		if (document.cookie.indexOf('skipicebrowsercheck=1') != -1) {
			Kore.environment.browser.supported = Kore.browserSupport.SUPPORTED;
		}
		if (
			Kore.environment.browser.supported == Kore.browserSupport.MAYBE
				||
			Kore.environment.browser.supported == Kore.browserSupport.NOTSUPPORTED
				||
			!Kore.environment.browser.isVersionSupported
				||
			!Kore.environment.flash.isValid
		) {
			Kore.environmentInvalidCallback();
		} else {
			Kore.environmentValidCallback();
		}
	}
};

/**
 * Make a call and decide what actions to make depending on whether the current 
 * browser/flash/version of includes folder is supported or not
 */
Kore.validateEnvironment();
