/* bookmark.js

	Purpose:
		
	Description:
		
	History:
		Mon Nov  3 19:34:25     2008, Created by tomyeh

Copyright (C) 2008 Potix Corporation. All Rights Reserved.

	This program is distributed under LGPL Version 2.1 in the hope that
	it will be useful, but WITHOUT ANY WARRANTY.
*/
zk.bmk = (function () { //used internally
	var _curbk = '', _initbk = '';

	function getBookmark() {
		var nm = location.hash,
			j = nm.indexOf('#');
		nm = j >= 0 ? decodeURIComponent(nm.substring(j + 1)) : '';
		return nm || _initbk;
	}
	/** Checks whether the bookmark is changed. */
	function checkBookmark() {
		var nm = getBookmark();
		if (nm != _curbk) {
			_curbk = nm;
			zAu.send(new zk.Event(null, 'onBookmarkChange', nm), 1);
			zk.bmk.onURLChange();
		}
	}
	function _simplifyURL(url) {
		var j = url.lastIndexOf(';');
		if (j >= 0) url = url.substring(0, j);
		j = url.lastIndexOf('#');
		if (j >= 0) url = url.substring(0, j);
		j = url.lastIndexOf('?');
		if (j >= 0) url = url.substring(0, j);
		return url;
	}
	function _toHash(nm, hashRequired) {
		nm = encodeURIComponent(nm);
		return (!hashRequired && zk.webkit) || !nm ? nm : '#' + nm;
	}
	function _bookmark(nm, replace) {
		if (_curbk != nm) {
			var oldnm = _curbk;
			_curbk = nm; //to avoid loop back the server

			if (replace)
				location.replace(location.href.replace(/#.*/, '') + _toHash(nm, true));
			else
				location.hash = _toHash(nm);
			zk.bmk.onURLChange();
		}
	}

	var _startCheck = function () {
		_startCheck = null;
		checkBookmark();
		jq(window).on('hashchange', checkBookmark);
		// Kept for a workaround that history.pushState() never causes a hashchange event to be fired
		setInterval(checkBookmark, 250);
			//Though IE use bookmark.html, timer is still required
			//because user might specify URL directly
	};
	zk._apac(_startCheck); //see mount.js (after page AU cmds)

	return {
		checkBookmark: checkBookmark,
		/** Sets a bookmark that user can use forward and back buttons */
		bookmark: function (nm, replace) {
			if (_startCheck)
				_curbk = _initbk = nm;
			else
				(zk.bmk.bookmark = _bookmark)(nm, replace);
		},
		/** called when bookmark.html is loaded*/
		onIframeLoaded: zk.ie < 11 ? function (src) {
			var j = src.indexOf('?'),
				nm = j >= 0 ? src.substring(j + 1) : '';
			location.hash = nm ? /*zk.safari ? nm:*/ '#' + nm : '';
			checkBookmark();
		} : zk.$void,

		/** check if URL is changed */
		onURLChange: function () { //called by mount.js
			try {
				var ifr = window.frameElement;
				if (!parent || parent == window || !ifr) //not iframe
					return;

				var l0 = parent.location, l1 = location,
					url = l0.protocol != l1.protocol || l0.host != l1.host
					|| l0.port != l1.port ? l1.href : l1.pathname,
					j = url.lastIndexOf(';'), k = url.lastIndexOf('?');
				if (j >= 0 && (k < 0 || j < k)) {
					var s = url.substring(0, j);
					url = k < 0 ? s : s + url.substring(k);
				}
				if (l1.hash && '#' != l1.hash) url += l1.hash;

				var $ifr = jq(ifr);
				if ($ifr.attr('z_xsrc') != ifr.src) {//the first zul page being loaded
					var ifrsrc = ifr.src, loc = location.pathname;
					$ifr.attr('z_xsrc', ifrsrc);

				//The first zul page might or might not be ifr.src
				//We have to compare ifr.src with location
				//Gecko/Opera/Safari: ifr.src is a complete URL (including http://)
				//IE: ifr.src has no http://hostname/ (actually, same as server's value)
				//Opera: location.pathname has bookmark and jsessionid
				//Tomcat: /path;jsessionid=xxx#abc?xyz
					ifrsrc = _simplifyURL(ifrsrc);
					loc = _simplifyURL(loc);
					if (ifrsrc.endsWith(loc)
					|| loc.endsWith(ifrsrc)) { //the non-zul page is ifr.src
						$ifr.attr('z_xurl', url);
						return; //not notify if changed by server
					}
				}

				if (parent.onIframeURLChange && $ifr.attr('z_xurl') != url) {
					parent.onIframeURLChange(ifr.id, url);
					$ifr.attr('z_xurl', url);
				}
			} catch (e) { //due to JS sandbox, we cannot access if not from same host
				zk.debugLog(e.message || e);
			}
		}
	};
})();
