/**
 * Library to request a Window ID for each newly created window
 */
var WINDOW_IDS_ENABLED = true; 

var WINDOW_IDS_SKIP = false; 

var WINDOW_ID_PARAM = 'at.onlinegroup.core.windowId';
var WINDOW_PARENT_ID_PARAM = 'at.onlinegroup.core.parentWindowId';
var WINDOW_ID_COOKIE = 'at.onlinegroup.core.broker3.servlet.Broker3.currentWindowNode';
var WINDOW_PARENT_ID_COOKIE = 'at.onlinegroup.core.broker3.servlet.Broker3.currentParentWindowNode';
var REQ_PARAM_CREATE_NEW_WINDOW_ID = "at.onlinegroup.core.windowId.createNew";

/**
 * Class to hold a single Window ID
 */
function WindowId(id) {
	var m_id;
	
	if(id && id.length>0) {
		m_id = id;
		//alert('Reuse WindowId: ' + m_id);
	}else{
		m_id = generateWindowId();
		//alert('Created new WindowId: ' + m_id);
	}
	register();
	
	
	/**
	 * Registers for all events
	 */
	this.register = register;
	function register() {
		registerOnBeforeUnload();
		registerOnLoad();
		registerOnClose();
	}
	
	/**
	 * Registers this class for the on beforeunload event
	 */
	this.registerOnBeforeUnload = registerOnBeforeUnload; 
	function registerOnBeforeUnload() {
		Event.observe(window, 'beforeunload', function() {
			if (!WINDOW_IDS_SKIP) {
			  createCookie(WINDOW_ID_COOKIE,winid.getId(),0);
			  var o=getOpenerId();
			  if(o!=null) createCookie(WINDOW_PARENT_ID_COOKIE,o,0);
			  //alert("on before unload - winid: " + winid.getId() + '; opener: ' + o);
			}
		}
		);
	}
	
	/**
	 * Registers this class for the on create event
	 */
	this.registerOnLoad = registerOnLoad; 
	function registerOnLoad() {
		Event.observe(window, 'load', function() {
		  eraseCookie(WINDOW_ID_COOKIE);
		  eraseCookie(WINDOW_PARENT_ID_COOKIE);
		  //winid.injectId();
		  //alert("on load - winid: " + winid.getId() + '; opener: ' + getOpenerId());
		}
		);
	}
	
	/**
	 * Registers this class for the onclose event
	 * TODO does not work?
	 */
	this.registerOnClose = registerOnClose; 
	function registerOnClose() {
		Event.observe(window, 'close', function() {
			//alert('close code');
		}
		);
	}	
	
	/**
	 * Generates a new window Id
	 */
	this.generateWindowId = generateWindowId;
	function generateWindowId() {
		var ID_PREFIX = 'C';
		var dt = new Date();
		var ts = dt.getTime()
		var nid = ID_PREFIX + ts;
		return nid;
	}
	
	/**
	 * Returns the current window id
	 */
	this.getId = getId;
	function getId() {
		return m_id;
	}
	
	/**
	 * Returns true if this id was generated by the client
	 */
	this.isClientGenerated = isClientGenerated;
	function isClientGenerated() {
		return m_id.charAt(0) == 'C';
	}
	
	/**
	 * Returns true if this id was generated by the server
	 */
	this.isServerGenerated = isServerGenerated;
	function isServerGenerated() {
		return !isClientGenerated();
	}
	
	/**
	 * Inject the window id in all forms and links
	 */
	this.injectId = injectId;
	function injectId() {
		injectIntoLinks();
		injectIntoForms();
	}
	
	/**
	 * Attach opener ids
	 */
	this.getOpenerId = getOpenerId;
	function getOpenerId() {
		if(window.opener && window.opener.winid) {
			return window.opener.winid.getId();
		} else if (getParentId()) {
			return getParentId();
		}
		return null;
	}
	
	/**
	 * Return parent id, if parent isn't caller itself (dummy name-comparision)
	 */
	this.getParentId = getParentId;
	function getParentId() {
		try {
			if (self.parent && self.parent.name!=self.name && self.parent.winid) {
				return self.parent.winid.getId();
			}
		}catch(e) {
		}
		return null;
	}
	
	/**
	 * Check wether the given form has a window id, inject one if not
	 */
	function injectIntoForm(f) {
    Event.observe(f, 'submit', function() {
		  var o=getOpenerId();
		  if(o!=null) createCookie(WINDOW_PARENT_ID_COOKIE,o,0);
		});	
	}
	
	/**
	 * Inject window id in all forms
	 */
	function injectIntoForms() {
		var i=0;
		for(i=0;i<document.forms.length;i++) {
			injectIntoForm(document.forms[i]);
		}
	}
	
	/**
	 * Append request Parameter to Link
	 */
	function injectIntoLink(l) {
		Event.observe(l, 'click', function() {
		  var o=getOpenerId();
		  alert(l + ": " + o);
		  if(o!=null) createCookie(WINDOW_PARENT_ID_COOKIE,o,0);
		});
	}
	
	/**
	 * Inject window id in all Links
	 */
	function injectIntoLinks() {
		var i=0;
		for(i=0;i<document.links.length;i++) {
			injectIntoLink(document.links[i]);
		}
	}

	
}

/*
 * Set or override the parentWindowId-, windowId- and createNew-url-parameters in a parameter-string
 */
function ogcore_setWindowIdParams(params, forPopup, useParentAsWindowId) {
  if (winid && ogcore_isOfType(params, 'string')) {
  	// convert param-string into hash
	  
    var _w = new Hash(params.toQueryParams());
    
    _w = ogcore_setWindowIdParamsInHash(_w, forPopup, useParentAsWindowId);
    
		// convert hash into param-string
		params = _w.toQueryString();
  }
  
  return params;
}

/*
 * Set or override the parentWindowId-, windowId- and createNew-parameters in a parameter hash
 */
function ogcore_setWindowIdParamsInHash(paramsHash, forPopup, useParentAsWindowId) {
	if(winid) {
	paramsHash=new Hash(paramsHash); //ensures that objects are converted to Hash
    // set windowId-params as needed
    if ( useParentAsWindowId ) {
    	try {
    		paramsHash.unset(WINDOW_PARENT_ID_PARAM);
    		paramsHash.unset(REQ_PARAM_CREATE_NEW_WINDOW_ID);
    	}catch(e) {
    		// ingoring remove errors
    	}
      paramsHash.set(WINDOW_ID_PARAM, winid.getOpenerId());
    } else if (forPopup) {
      paramsHash.set(WINDOW_PARENT_ID_PARAM, winid.getId());
      paramsHash.set(REQ_PARAM_CREATE_NEW_WINDOW_ID, 'true');
      paramsHash.unset(WINDOW_ID_PARAM);
    } else {
		  paramsHash.set(WINDOW_ID_PARAM,winid.getId());
		  if (winid.getOpenerId() != null) paramsHash.set(WINDOW_PARENT_ID_PARAM,winid.getOpenerId());
		}
	    
	}
	
	return paramsHash;
}

/*
 * Set or override the parentWindowId-, windowId- and createNew-url-parameters
 */
function ogcore_setWindowIdParamsInUrl(url, forPopup, useParentAsWindowId) {

	// separate parameters from url
  var urlParts = url.split("?", 2);
  var urlWithoutParams = urlParts[0];
  params = ogcore_setWindowIdParams(url, forPopup, useParentAsWindowId);	// params.toQueryParams() manages to ignore everything else than parameters
  
  return urlWithoutParams + "?" + params;
  
}
