var myLytebox;

//declare root passenger name space
function passenger(){}

//declare util name space
passenger.util = function(){}

//declare xml name space
passenger.xml = function(){}

//declare common name space
passenger.common = function(){}

/*
This function si called on load of every page. This can be used to initialize page
specific information. As a generic logic following infomration is initialized:
1. Initialize all the table sorting for tables that has client sort enabled. 
*/
function initialize() {
	var tableList = document.getElementsByTagName("table");
	var currentTable;
	for (var i=0; i < tableList.length  ; i++ )	{
		currentTable = tableList[i];
		if (currentTable.getAttribute("isClientSortEnabled")) {
			var st = new SortableTable(currentTable,  ["CheckBox", "Number", "String", "String", "Date", "None"]);
		}
	}
	try{
		initializePage();
	}catch(ex){
		//initialize page is not defined for this page
	}
}

/**
 * This function will replace *special* characters inserted by applications like
 * Microsoft Word with friendlier versions. This prevents blocks or ?'s in the
 * text that is submitted to the application.
 */
passenger.util.cleanText = function(str){
	var replacements, regex, key, textnodes, node, s;
	replacements = {
	    "\xa0": " ",
	    "\xa9": "(c)",
	    "\xae": "(r)",
	    "\xb7": "*",
	    "\u2018": "'",
	    "\u2019": "'",
	    "\u201c": '"',
	    "\u201d": '"',
	    "\u2026": "...",
	    "\u2002": " ",
	    "\u2003": " ",
	    "\u2009": " ",
	    "\u2013": "-",
	    "\u2014": "--",
	    "\u2122": "(tm)"};
	regex = {};
	for (key in replacements) {
	    regex[key] = new RegExp(key, 'g');
	}
    s = str;
    for (key in replacements) {
		s = s.replace(regex[key], replacements[key]);
    }
    return s;
}

/**
 * This function will replace &,<,>,\r\n, \n, \r characters with the appropriate 
 * HTML encoded strings.
 */
passenger.util.htmlEncodeText = function (text) {
	var textneu = text.replace(/&/,"&amp;");
	textneu = textneu.replace(/</,"&lt;");
	textneu = textneu.replace(/>/,"&gt;");
	textneu = textneu.replace(/\r\n/,"<br>");
	textneu = textneu.replace(/\n/,"<br>");
	textneu = textneu.replace(/\r/,"<br>");
	return(textneu);
}

passenger.util.htmldecodeText = function (text) {
	var textneu = text.replace("&amp;", /&/);
	textneu = textneu.replace("&lt;", /</);
	textneu = textneu.replace("&gt;", />/);
	textneu = textneu.replace("<br>", /\r\n/);
	textneu = textneu.replace("<br>", /\n/);
	textneu = textneu.replace("<br>", /\r/);
	return(textneu);
}

passenger.util.showPageTitle = function() {
	try {
		window.parent.document.getElementById("pageTitle").style.display = "block";
	} catch (Exception) {
		//alert("Unable to show page title: "+Exception);
	}
}

passenger.util.hidePageTitle = function() {
	try {
		window.parent.document.getElementById("pageTitle").style.display = "none";
	} catch (Exception) {
		//alert("Unable to hide page title: "+Exception);
	}
}

passenger.util.toggleElementDisplay = function (obj, objArrow) {
	try{
		var el = document.getElementById(obj);
		el.style.display=(el.style.display!='none'?'none':'');//Show or hide the element.
		if(objArrow != null) {
			var rightArrow = 'arrow_right.gif';
			var downArrow = 'arrow_down.gif';
			var elArrow = document.getElementById(objArrow);
			var arrowSrc = elArrow.src.toString();
			var arrowFQP = arrowSrc.substring(0, arrowSrc.lastIndexOf("/")+1);
			var arrowFile = arrowSrc.substring(arrowSrc.lastIndexOf("/")+1, arrowSrc.length);
			elArrow.src=(!passenger.util.compareStrings(arrowFile, rightArrow)?arrowFQP+rightArrow.toString():arrowFQP+downArrow.toString());//Spin the arrow
		}
		passenger.util.resizeFrame('content');
		passenger.util.adjustFrame('content', false);//Resize IFrame
	}catch(Exception){
		dojo.debug("Exception in toggleElementDisplay: "+Exception);
		passenger.util.adjustFrame('content', false);//Resize IFrame
	}	
}

passenger.util.openElementDisplayByDefault = function () {
	try{
		//'playerRow', 'playerArrow'
		if(document.getElementById("playerRow")) {
			passenger.util.toggleElementDisplay('playerRow', 'playerArrow');
			passenger.util.toggleElementDisplay('playerExtra', null);
		} else if (document.getElementById('docRow')) {
			passenger.util.toggleElementDisplay('docRow', 'docArrow');
			passenger.util.toggleElementDisplay('docExtra', null);
		}
		passenger.util.resizeFrame('content');
		passenger.util.adjustFrame('content', false);//Resize IFrame
	}catch(Exception){
		dojo.debug("Exception in openElementDisplayByDefault: "+Exception);
		passenger.util.adjustFrame('content', false);//Resize IFrame
	}	
}

/**
 * Close the elements of the File Gallery when necessary
 */
passenger.util.closeElement = function (obj, objArrow) {
	try{
		var el = document.getElementById(obj);
		if(el) {
			el.style.display='none';//Hide the element.
			if(objArrow != null) {
				var rightArrow = 'arrow_right.gif';
				var elArrow = document.getElementById(objArrow);
				var arrowSrc = elArrow.src.toString();
				var arrowFQP = arrowSrc.substring(0, arrowSrc.lastIndexOf("/")+1);
				var arrowFile = arrowSrc.substring(arrowSrc.lastIndexOf("/")+1, arrowSrc.length);
				elArrow.src=arrowFQP+rightArrow.toString();//Spin the arrow
			}
		}
		passenger.util.resizeFrame('content');
		passenger.util.adjustFrame('content', false);//Resize IFrame
	}catch(Exception){
		dojo.debug("Exception in closeElement: "+Exception);
		passenger.util.adjustFrame('content', false);//Resize IFrame
	}	
}

passenger.util.scrollToTop = function() {
	if(window.parent.document.getElementById("isHomePage") != null) {
		window.parent.scroll(0,0);
	}
}

passenger.util.getWindowProperties = function(){
	var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1];
	var headerSize=dojo.html.getBorderBox(parent.document.getElementById("innerContentTop")).height;
	var footerSize=dojo.html.getBorderBox(parent.document.getElementById("innerContentBottom")).height;
	var menuSize=dojo.html.getBorderBox(parent.document.getElementById("menuHolderRow")).height;	
	var titleSize= 0; //The landing page does not have a title field
	if(!document.getElementById('isLanding')) { // Only initialize this value if the page is not the landing page.
		titleSize=dojo.html.getBorderBox(parent.document.getElementById("pageTitle")).height;
	}
	var hfmtSize=headerSize+footerSize+menuSize+titleSize+4;
	return {
		extraHeight: parseFloat(getFFVersion)>=0.1?5:0,
		windowHeight: ((parent.getHomeViewPort()).height)-hfmtSize,
		hfmtSize: hfmtSize
	}
}

/**
 * Function to adjust the size the frame based on the content of the page.
 * @param id -- id of the frame that need to be adjusted
 * @param buffer -- boolean to signal if a buffer should be provided
 * @usage -- This method should be called on load the frame body
 */
passenger.util.adjustFrame = function(id, buffer){
	try {
		var props = passenger.util.getWindowProperties();
		var rightShadowDiv=parent.document.getElementById("rightShadowDiv");
		var leftShadowDiv=parent.document.getElementById("leftShadowDiv");
		var frame=parent.document.getElementById(id);
		var frameHeight=0;
		var frameWidth=0;
		if(frame){
			frame.style.display="";//Clear any existing style.
			
			if (document.all){//Internet Explorer 5 and above
				frameHeight=document.body.scrollHeight;
				frameWidth=document.body.scrollWidth;
				if(frameHeight + 60 <= props.windowHeight){
					frame.style.height=props.windowHeight;
				}else{
					frame.style.height=frameHeight + 60;	
				}
			}else if(document.documentElement && document.documentElement.scrollHeight ) {//Mozilla (FireFox, Safari, Netscape)
				if(document.getElementById('centerContentInFrame')) {
					frameHeight=document.getElementById('centerContentInFrame').scrollHeight;
				} else if(document.getElementById('centerContent')){
					frameHeight=document.getElementById('centerContent').scrollHeight;
				} else if(document.getElementById('centerContentInFrameLeftAlign')){
					frameHeight=document.getElementById('centerContentInFrameLeftAlign').scrollHeight;
				} else {
					frameHeight=document.documentElement.scrollHeight;
				}
				frameWidth=document.documentElement.scrollWidth;
				if(frameWidth<=1){
					try{
						frameWidth=document.body.scrollWidth;
					}catch(Exception){
						//do nothing
					}
				}
				if(frameHeight + 50 <= props.windowHeight){
					frame.style.height=(props.windowHeight)+"px";
				} else {
					if(buffer){
						frame.style.height=(frameHeight+props.extraHeight + 50)+"px";
					} else{
						frame.style.height=(frameHeight + 50)+"px";
					}
				}
			}else{//Other Browsers (opera, etc).
				frameHeight=document.documentElement.scrollHeight;
				frameWidth=document.documentElement.scrollWidth;
				frame.style.height=(frameHeight)+"px";
			}
			var shadowSize=props.hfmtSize+parseInt(frame.style.height.substring(0,frame.style.height.length-2));
			rightShadowDiv.style.height=shadowSize+"px";
			leftShadowDiv.style.height=shadowSize+"px";
			if (document.all){//Internet Explorer 5 and above
				frame.style.width=(frameWidth)+"px"
			}else if(document.documentElement && document.documentElement.scrollWidth ) {//FireFox, Safari, Netscape
				frame.style.width=(frameWidth)+"px";
			}else{//Other Browsers (opera, etc)
				frame.style.width=(frameWidth)+"px"
			}
		}
	}catch(Exception){
		dojo.debug("Exception in adjustFrame: "+Exception);
	}
}

/**
 * Compare two arrays and determine if they are equal.
 */
passenger.util.compareArrays = function(current, last) {
	if(current == null) {
		return false;//Nothing to compare.
	} else if (last == null) {
		return true;//If last is null, must be first time.
	}
	if(current.length != last.length) {
		return true;//Size difference indicates change.
	} else {
		for(var i=0; i< current.length; i++) {
			if(current[i] != last[i]) {
				return true;//Contents are different.
			}
		}
		return false;//Contents are the same.
	}
}

passenger.util.compareStrings = function(source, target) {
	if(source == null || target == null) {
		return false;//Nothing to compare
	} else if(source.length != target.length){
		return false;//Strings are different
	} else {
		return source == target;//Compare string contents.
	}
}

passenger.util.resizeFrame = function(id){
	parent.document.getElementById(id).style.height="0px";
}

passenger.util.hideElement = function(element){
	document.getElementById(element).style.visibility = "hidden";
	return false;
}

passenger.util.showElement = function(element){
	document.getElementById(element).style.visibility = "visible";
	return true;
}

/**
 * Function used to change the image based on mouse over and mouse out.
 * TO use this function image element should make sure that it has the 
 * attributes for mouseOverImage and mouseOffImage. This will take care of internationalization also
 * @param currentElement -- current image element
 * @param isMouseOver -- true for mouse over and false for mouse out 
 */
passenger.util.handleImageForMouseAction = function(currentElement, isMouseOver) { 	
	if (isMouseOver) {
		currentElement.src = currentElement.getAttribute("mouseOverImage");	
	}else{
		currentElement.src = currentElement.getAttribute("mouseOutImage");				
	}
}

/**
 * method to log the debug  information in a debug window
 */
//function logDebugMessage(debugString) {
//	dojo.debug(debugString);		
//}


//create an element with given name and set the value in a given form
passenger.util.createHiddenElement = function (formObject, elementName, elementValue) {

	//if the lement is already there then update the same
	//newElement = fetchElementFromList(formObject.elements, elementName);
	// Replacing this method to check if an element already exist in the form
	newElement = eval("formObject."+elementName);

	if ( newElement == null ) {
		newElement = document.createElement("INPUT");
		newElement.type = "hidden";
		newElement.value = elementValue;
		newElement.name = elementName;
		newElement.id= elementName;
		formObject.insertBefore(newElement, null);
	}
	else{
		newElement.value = elementValue;
	}
}

/**
 * Get handle to content object from the current frame
 */
passenger.util.getContentObject = function (currentFrameObject) {
	var contentFrame = null;
	var frames = window.parent.frames;

	for(var i=0; i < frames.length; i++) {
		if (frames[i].name == "content") {
			contentFrame = frames[i];
			break;
		}		
	}	
	return contentFrame;
}

passenger.util.getHomeObject = function () {
	return window.parent;
}

passenger.util.parseBoolean = function(s) {
	if (!s) return false;
	s = s.toString().toLowerCase();
 	return s == "true" || s == "yes" || parseInt(s) > 0;
}

passenger.util.getHtmlSubmitEvent = function (){
	var myFormSubmitEvent;
	if (document.createEvent){
		myFormSubmitEvent = document.createEvent("HTMLEvents");
		myFormSubmitEvent.initEvent("submit", true, true);
	}else{
		myFormSubmitEvent = document.createEventObject();
	}
	return myFormSubmitEvent;
}

passenger.util.getRootTargetName = function () {
	return "_top";
}

/* have to use this to pull style values out of the style sheet */
passenger.util.getStyle = function(oElm, strCssRule){
    var strValue = "";
    if(document.defaultView && document.defaultView.getComputedStyle){
        strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
    }
    else if(oElm.currentStyle){
        strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
            return p1.toUpperCase();
        });
        strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
}

passenger.xml.getChildElementById = function(parentElement, childElementId) {
	var childElement = null;
	
	if(parentElement.childNodes == null || parentElement.childNodes.length == 0) {
		throw new passenger.exception.UIException("Child Nodes not found");
	}
	
	var childElementlength = parentElement.childNodes.length;
	
	for(var i=0; i < childElementlength; i++) {
		
		try {
			if(parentElement.childNodes[i].getAttribute("id") == childElementId){
				childElement = parentElement.childNodes[i];
			}
		}catch(exception){
			//if the node is text ndoe we will get thsi exception
		}
		
		if(childElement!= null) {
			break;
		}
	}
	
	return childElement;
}

passenger.xml.getChildElementByName = function(parentElement, childElementName) {
	var childElements = parentElement.getElementsByTagName(childElementName);
	
	if(childElements.length > 0 ) {
		return childElements[0]; 
	}else{
		return null;
	}	
}

passenger.xml.getChildElementsByName = function(parentElement, childElementName) {
	var childElements = parentElement.getElementsByTagName(childElementName);
	
	if(childElements.length > 0 ) {
		return childElements; 
	}else{
		return null;
	}	
}

//PeriodicalInvoker object.
passenger.PeriodicalInvoker = function(intervalMilliseconds, method, args) {
    this.intervalMilliseconds = intervalMilliseconds;
    this.method = method;
    this.args = args;
    this.delegate = null;
    this.state = false;
}

dojo.lang.extend(passenger.PeriodicalInvoker, {
    intervalMilliseconds: 1000,
    method: null,
    args: null,
    delegate: null,
	
    start: function(){
        dojo.require("dojo.animation.*");
        dojo.require("dojo.html");
        dojo.require("dojo.event.*");
        var line = new dojo.math.curves.Line([1],[1]);
        delegate = new dojo.animation.Animation(line, this.intervalMilliseconds, 0, -1, this.intervalMilliseconds);
        dojo.event.connect(delegate, "onEnd", this, this._invoke);
        delegate.play(true);
        this.state = true;
    },

	stop:function() {
		delegate.stop(true);
		this.state = false;
	},
	
	getState:function(){
		return this.state;
	},
	
    _invoke: function(e){
    	
    	if(!this.args){
    		this.args = [];	
    	}
    	try{
       		this.method.apply(this, this.args);
    	}catch(exception){
    		//ignore
    	}
    }
});

/**
 * Function that can be called on initialization of any page.
 */
passenger.common.initPage = function() {
	try {
		window.parent.cleanLytebox();
	} catch (exception) {
		// Do nothing
	}
	
	try{
		if(document.getElementById("isHomePage") == null) {
			passenger.util.adjustFrame('content', true);
			window.top.setPageTitle(document.getElementById("AboutInfo.ScreenName").innerHTML);	
		}		
		
		//call initialize for the page that can be implemented by each page
		if(passenger.common.initialize){
			passenger.common.initialize();
		}
		if(document.getElementsByTagName) {
			var anchors = document.getElementsByTagName('a');
			for(index in anchors) {
				if(anchors[index]) {
					anchors[index].onfocus = function() {
						if(this.blur) {
							this.blur();
						}
					};
				}
			}
		}
	}catch(exception){
		//do nothing
	}
};

passenger.common.unloadPage = function() {
	try{
		var windowHeight = passenger.util.getWindowProperties().windowHeight;
		parent.document.getElementById("content").style.height = windowHeight+"px";		
		if (document.all){//Internet Explorer 5 and above
			parent.document.getElementById("content").style.width= "1px";
		}else{//Other Browsers (mozilla, safari, opera, etc).
			parent.document.getElementById("content").style.width= "0px";				
		}
	}catch(exception ){
		dojo.debug("Exception in passenger.common.unloadPage: error resizing page");
	}
}

passenger.common.ignoreEnterKeyPressed = function(anEvent){
	var keycode;
	if (window.event) keycode = window.event.keyCode;
	else if (anEvent) keycode = anEvent.which;
	else return true;
	if (keycode == 13) {
		return false;
	}else{
		return true;
	}
}

passenger.common.trapKeyboardEvents = function(event) {
	// Trap Esc(27), Backspace(8) and Enter(13) - Except bksp on 
	// text/textareas/password/flash, enter on textarea/submit/link
	if (typeof window.event != 'undefined') {
		document.onkeydown = function() {//IE
			var t=window.event.srcElement.type;
			var kc=window.event.keyCode;
			if(t) {
				return ((kc != 8 && kc != 13 && kc != 27) || (t == 'text' && kc != 27) ||
				(t == 'textarea' && kc != 27) || (t == 'button' && kc == 13) ||
				(t == 'submit' && kc == 13) || (t == 'password' && kc != 27) ||
				(t == 'flash' && kc != 27 && kc != 13) || (t == '' && kc == 13));
			}
			//Dont allow the char to continue.
			return false;
		}
	} else {
		document.onkeypress = function(event) {// FireFox/Others
			var t=event.target.type;
			var kc=event.keyCode;
			if(t) {
				return ((kc != 8 && kc != 13 && kc != 27) || (t == 'text' && kc != 27) ||
				(t == 'textarea' && kc != 27) || (t == 'button' && kc == 13) ||
				(t == 'submit' && kc == 13) || (t == 'password' && kc != 27) ||
				(t == 'flash' && kc != 27 && kc != 13) || (t == '' && kc == 13));
			}
			//Dont allow the char to continue.
			return false;
		}
	}
}

passenger.common.setFocusOnInput = function() {
	try {
		var els = document.getElementsByTagName('input');
		for(i=0; i<els.length; i++) {
			var el = els[i];
			if(el.type == 'text' || el.type == 'textarea') {
				el.focus();
				return true;
			}
		}
		return false;
	}catch(Exception) {
		dojo.debug("setFocusOnInput: "+Exception);
	}
}

/**
 * This method retrieves all the anchors in the page and, if they are set to a relative target "external",
 * will add the _blank value to the anchor's target attribute. This is necessary for the page to validate
 * as an XHTML strict page.
 */
passenger.common.handleExternalLinks = function() {
	if(!document.getElementsByTagName) return false;
	var anchors = document.getElementsByTagName('a');
	for(index in anchors) {
		if(anchors[index].getAttribute && 
				anchors[index].getAttribute("href") && 
						anchors[index].getAttribute("rel") == "external") {
			anchors[index].target = "_blank";
		}
	}
};

/**
 * Initialize the lytebox components on the page
 */
passenger.common.initLyteLink = function() {
	// Do not initialize the lytebox elements if already initialized.
	if(!myLytebox) {
		myLytebox = new LyteBox();
	}
};

passenger.common.showUsernameTip = function (element) {
	if(document.getElementById) {
		var imageDiv = document.getElementById('profileImage');
		var tipDiv = document.getElementById('username_tip');
		var profileDiv = document.getElementById('profileContent');
		if(imageDiv && tipDiv && profileDiv) {
			var imageWidth = imageDiv.clientWidth;
			if(imageWidth > 0) {
				if(document.all) { // This is IE specific code
					tipDiv.style.left = (imageDiv.clientWidth + 40) + 'px';
				} else {
					tipDiv.style.left = (element.offsetLeft + 10) + 'px';
				}
				tipDiv.style.top = '65px';
				tipDiv.style.display = "block";
				if(element.offsetWidth > profileDiv.clientWidth) {
					/* If the profile content is smaller than it needs to be, resize it */
					profileDiv.style.width = (240 - imageDiv.clientWidth) + 'px';
				}
				
			}
		}
	}
};

passenger.common.hideUsernameTip = function() {
	if(document.getElementById) {
		var tipDiv = document.getElementById('username_tip');
		if(tipDiv) {
			tipDiv.style.display = "none";
		}
	}
};
