/*----------------------------------------------------------------------------\
|							Askia Script Objects							  |
|-----------------------------------------------------------------------------|
|                          Created by Askia Company							  |
|							(http://www.askia.com)							  |
|-----------------------------------------------------------------------------|
| The AskiaScript is the main javascript library of Askia					  |
| It will manage integrate all needed javascript files of Askia				  |
|-----------------------------------------------------------------------------|
|							Copyright Askia © 1994-2006						  |
|-----------------------------------------------------------------------------|
| {No Dependencies}															  |
|-----------------------------------------------------------------------------|
| 2006-05-23 |V 1.0.0														  |
|			 |+ AUTO-LOAD THE RESOURCES										  |
|			 |	Load the Javascript files into the html page				  |
|			 |	Load the resources files of the Javascripts	(pictures...)	  |			
|-----------------------------------------------------------------------------|
| 2006-11-06 |V 1.1.0														  |
|			 |+ Add the management of custom control						  |
|-----------------------------------------------------------------------------|
| 2007-06-29 |V 1.0.1														  |
|			 |+ Add the cursor constants									  |
|-----------------------------------------------------------------------------|
| 2006-11-29 |V 1.1.0														  |
|			 |+ Add the XmlLoader object in the framework					  |
|			 |+ Management of Plug-Ins										  |
| 2007-01-11 |+ Corrrection: Block the previous of browser					  |
| 2007-11-13 |+ Add the ranking management into the default framework         |
| 2009-05-06 |+ Add management of Flash										  |
|			 |+ Add the urlEncode() urlDecode() format() methods		      |
|-----------------------------------------------------------------------------|
| Created 2006-05-23 | All changes are in the log above. | Updated 2009-05-06 |
|-----------------------------------------------------------------------------|
|														All rights reserved	  |
|Askia - AskiaScript - API Version 1.1.0		Copyright Askia © 1994-2009   |
\---------------------------------------------------------------------------- */

/* -----
	Working on:
		Internet Explorer 			   [Tested on 6 / 7]
		NetScape (since the version 6) [Tested on 6 / 7 / 8]
		Opera (since the version 7)	   [Tested on 7 / 8] (no calendar appear on version 7)
		FireFox						   [Tested on 1 / 2]

	Not working on: 
		Opera 3 / 5 / 6
		NetScape 4 
		
----- */


/* ====
	Set-up browser checks and add emulator
==== */
var isOpera   = /opera|opera/i.test(navigator.userAgent);
var isIE	  = !isOpera && /msie/i.test(navigator.userAgent);			// preventing opera to be identified as ie
var isMozilla = !isOpera && /mozilla\/5/i.test(navigator.userAgent);	// preventing opera to be identified as mz
var isNS6	  = isMozilla && /Netscape6/i.test(navigator.userAgent);	

//Constants to have the version of script
var VERSION_OF_SCRIPTS="1.0.0";
var LATEST_VERSION_OF_SCRIPTS="1.1.0";

//Other constants
var UNDEFINED='undefined';

//Cursors
var CURSOR_WAIT="wait";

//Special keys of keyboard
var KEY_BACK=8;
var KEY_ENTER=13;
var KEY_PAGEUP=33;
var KEY_PAGEDOWN=34;
var KEY_END=35;
var KEY_HOME=36;
var KEY_LEFT=37;
var KEY_UP=38;
var KEY_RIGHT=39;
var KEY_DOWN=40;
var KEY_INS=45;
var KEY_DEL=46;


//Extension
var EXTENSION_CSS='css';

//Files
var FILENAME_SETTINGS_XML='AskiaScript.xml';
var FOLDER_PLUGINS='PLUGINS';
var FOLDER_SKINS='SKINS';

//Add method getElementById() in the document 
//(for IE4 and other browser which don't support the getElementById method)
if (isIE && document.getElementById == null) {	
	document.getElementById = function(sId) {
			return document.all[sId];
		};
	}

//Add new method in the Date object 
//(for NS6 and other browser which don't suppport the toDateString method)
if (typeof (Date.prototype.toDateString)==UNDEFINED){
		Date.__arrDays=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
		Date.__arrMonths=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
		Date.prototype.toDateString=function(){
				var strDate=Date.__arrDays[this.getDay()] + ' ' + Date.__arrMonths[this.getMonth()] + ' ' + formatNumber(this.getDate()) + ' ' + this.getFullYear();
				
				//Format number with 2 digits
				function formatNumber(number){
						var sReturn=number;
						if (parseInt(number)<10)sReturn = "0" + parseInt(number);
						return sReturn;
					}
				return strDate;
			}
	}

/* ===
	Lock the previous button of browser
=== */
try {
		window.history.forward(1);
	}
catch(ex){/* Do nothing */}


/* ====
	AskiaLibrary
	Objects which content the name of different javascript files
==== */
var AskiaLibrary={
		//Mozilla emulator to retrieve some IE features into Mozilla
		MOZILLA_EMULATOR	:   'IEEmulatorForMoz.js',
		//Manage the Questions/Responses (Semi-open, ranking...)
		COMMON				:	'Common.js',
		//Manage the navigation (Previous/Next/Pause)
		NAVIGATION			:   'Nav.js',
		//Manage the validation of form
		VALIDATOR			:   'FieldValidator.js',
		//Manage the error messages
		ERROR_MESSAGES		:   'ErrorMessages.js',
		//Manage the live calculation
		CALCULATOR			:	'Calculator.js',
		//Manage the calendar
		CALENDAR			:   'Calendar.js',		
		//Manage the sliders
		SLIDER				:   'Slider.js',
		//Manage the ranking
		RANKING             :   'Ranking.js',
		//Manage the tool tip text
		TOOLTIPTEXT			:   'ToolTipText.js',
		//Manage the string
		STRINGBUILDER		:   'StringBuilder.js',
		//Manage the translation of script
		TRANSLATION			:	'Translation.js',
		//Manage the custom controls
		CUSTOMCONTROL		:   'CustomControl.js',
		//Manage the xml loader
		XMLLOADER			:   'XmlLoader.js',
		//Manage the plugins
		PLUGINS				:   'PlugIns.js',
		//Manage the flash integration
		FLASH				:   'Flash.js'
	};
var AskiaCSS={
		//CSS of ToolTip text
		TOOLTIPTEXT			:   'ToolTipText.css',
		//Css of calendar
		CALENDAR			:	'Calendar.css',
		//Css of ranking (for drag and drop
		RANKING             :   'Ranking.css'
	};
/* ====
	AskiaScript object
====*/
var AskiaScript={
		//GLOBAL PROPERTIES OF SURVEY
		intNameOfSurvey				: '',
		extNameOfSurvey				: '',
		languageId					: null,
		
		//ARCHITECTURE OF SERVER
		pathOfResources				: '../Resources/',
		pathOfScripts				: '../Scripts/',
		pathSeparator				: '/',
		_CSSFolderName				: 'CSS',
		//
		_addedStyleSheet			: {},
		
		//LOAD THE DIFFERENT LIBRARIES
		load						: function(version){
		        //Manage the load page
            	if (window.addEventListener){
                        window.addEventListener("load",function(){
                                AskiaScript._onPageLoad();
                            },false);
                }
                this._isPageLoaded();
                //Manage the version
				if (!version)version=1.0;
				if (parseFloat(version)==1.1)VERSION_OF_SCRIPTS=LATEST_VERSION_OF_SCRIPTS;
				
				//Search the separator of path :
				// '\' or '/' (local or web)
				this.pathSeparator=(this.pathOfScripts.indexOf(":\\")>0)?"\\":"/";		
				//Load the skin first
				if (this.skinName!=''){
				        document.write('<script language="javascript" src="' + this.pathOfScripts + FOLDER_SKINS + this.pathSeparator + this.skinName +  this.pathSeparator  + this.skinName +  '.js"></script>');
				    }
				//Add scripts
				for (var lib in AskiaLibrary){
						//Don't write the Mozilla Emulator when we are in IE
						if (!isMozilla && AskiaLibrary[lib]==AskiaLibrary.MOZILLA_EMULATOR)continue;
						if (AskiaLibrary[lib]==AskiaLibrary.TRANSLATION)continue;
						document.write('<script language="javascript" src="' + this.pathOfScripts + 'v' + VERSION_OF_SCRIPTS + this.pathSeparator + AskiaLibrary[lib] + '"></script>');
					}
				//At the end, add the scripts overwrite the translations
				//in all scripts
				if (this.languageId && this.languageId!=''){
						document.write('<script language="javascript" src="' + this.pathOfScripts + 'v' + VERSION_OF_SCRIPTS + this.pathSeparator + this.languageId + this.pathSeparator + AskiaLibrary.TRANSLATION + '"></script>');
					}
					
				//Add css
				for (var lib in AskiaCSS){
						this.addStyleSheet(this.pathOfScripts + 'v' + VERSION_OF_SCRIPTS + this.pathSeparator + this._CSSFolderName + this.pathSeparator + AskiaCSS[lib]);
					}
			},
        //Indicates if the page is completly loaded
		isPageLoaded                    :false,
		//Fire when the page is loaded
		_onPageLoad                     : function(){
		        this.isPageLoaded=true;
		        //Management of questions when the page is loaded
		        for (var i=0;i<QuestionHandler.childNodes.length;i++){
		            if (QuestionHandler.childNodes[i].isSorted){	
		                  //Create ranking element after the page load
		                  QuestionHandler.childNodes[i]._rankingElt=new Ranking(QuestionHandler.childNodes[i].id,QuestionHandler.childNodes[i].rankStyle);
		                }		        
		            }
		    },
		//Verify if the page is loaded or not
        _isPageLoaded                   : function(){
                if (!document.readyState || window.addEventListener)return;
                if(document.readyState=="complete")
                    AskiaScript._onPageLoad();
                else 
                    setTimeout("AskiaScript._isPageLoaded();" ,2);
		    },
        //Name of skin use by default
        skinName                        : '',
        //Collection of skins initiliazed in the document
        //Use the name of skin to retrieve it into the collection
        skinsCollection                 : {},
        initSkin                        : function(name){
                if (!this.skinsCollection[name])return;
                if (this.skinsCollection[name].isInit)return;
                var oSkin=new Object();
                oSkin.name=name;
                oSkin.single=CustomControl.fromSkin(name,'single');
                oSkin.multiple=CustomControl.fromSkin(name,'multiple');
                //Load the stylesheet now
                if (this.skinsCollection[name].single.useClass || this.skinsCollection[name].multiple.useClass){
                		var cssLink=this.pathOfScripts + FOLDER_SKINS + this.pathSeparator + name +  this.pathSeparator + name + '.css';
		                this.addStyleSheet(cssLink,true);
                    }
                oSkin.isInit=true;
                this.skinsCollection[name]=oSkin;
            },
		//Add style sheet into the document
		///<param name="onFly">Indicates if the stylesheet is added after the page load</param>
		addStyleSheet					: function(fileName,onFly){
				//Don't add a duplicate stylesheet
				if (this._addedStyleSheet[fileName])return;
				if (!onFly){
				        document.write('<link rel="stylesheet" href="' + fileName + '">');
				    }
                else {
                        //Double the backslash
		                var tmpBackSlash="__tmp__backslash__";
			                fileName=replace(fileName,'\\',tmpBackSlash);
			                fileName=replace(fileName,tmpBackSlash,'\\\\');
	                    //Import the style
	                    var st=document.styleSheets[0];
	                    if (typeof(st.addImport)!=UNDEFINED){
			                    st.addImport(fileName);
		                    }
	                    else{
			                    st.insertRule("@import url(" + fileName + ");", st.cssRules.length);
			                    if (isNS6){
					                    alert("You're browser not support the live importation of stylesheet.");
				                    }				
		                    }                        
                    } 
				this._addedStyleSheet[fileName]=true;
			},
		//State of navigation
		isNavigationInit			: false,
		
		//Init NavigatorHandler object
		initNavigation				: function(isFirstInit){
				if (this.isNavigationInit)return;
				if (this.initNavigation.__attemptsCount && !isFirstInit)return;
				
				//10 attempts (represent 5 seconds) to initialize the navigator
				if (!this.initNavigation.__attemptsCount){
						this.initNavigation.__attemptsCount=0;
					}
				if (this.initNavigation.__attemptsCount>=10)return;
				try{
						NavigatorHandler.init();
						this.isNavigationInit=true;
					}
				catch(ex){
						this.initNavigation.__attemptsCount++;
						setTimeout("AskiaScript.initNavigation(true);",500);					
					}
			},
		//Temporary stack of plug-in
		//Should be imported when the PlugInHandler is already loaded
		_tmpPlugInStack				: [],
		
		//Import a plug-in
		loadPlugIn					: function(plugInName){
				try {
					if (!PlugInHandler){
							addInStack(plugInName);
							return;
						}
					}
				catch (ex){
						addInStack(plugInName);
						return;
					}
				if (!PlugInHandler.isReady){
						addInStack(plugInName);
						return;
					}
					
				//Load the plug-in
				if (!PlugInHandler.all[plugInName])return;
				PlugInHandler.all[plugInName].load();
				
				//Add the plug-in in stack to load them when the pluginhandler is ready
				function addInStack(n){
						AskiaScript._tmpPlugInStack[AskiaScript._tmpPlugInStack.length]=n;
						
					}
			}
	};


///<summary>
///Format text using the parameters
///</summary>
///<param value="text">Text to format</param>
///<param value="params">Paramaters</param>
function format(text,params){
        var sText=text;
        for (var i=0;i<params.length;i++){
                sText =replace(sText,"{" + i + "}",params[i]);
            }
        return sText;
    }	
    
//Function to replace all characters of string
//Example of use : 
//replace("Text With Three Spaces"," ","_");
//Will return: "Text_With_Three_Spaces"
function replace(text,match,replacement){
		var sReturn=text;
		if (match=='')return sReturn;
		if (!text)return '';
		if (match==replacement)return sReturn;
		while(sReturn.indexOf(match)!=-1){
				sReturn=sReturn.replace(match,replacement);
			}
		return sReturn;
	}

//Position of elements
var ePosition={
		left	: 'left',
		top		: 'top'
	};
//Return the position of HTMLElement
//Example of use :
//var left=getPosition(document.getElementById("MyElement"),ePosition.left);
//var top=getPosition(document.getElementById("MyElement"),ePosition.top);
//alert("Left=>" + left + "px,Top=>" + top + "px");
function getPosition(htmlElt,pos){
		switch (String(pos).toLowerCase()) { 
			case ePosition.left : 
				var l=htmlElt.offsetLeft;
				var parent=htmlElt.parentNode;
				while (parent.offsetLeft){
						l +=parent.offsetLeft;
						parent=parent.parentNode;
					}
				return l;
				break; 

			case ePosition.top : 
				var t=htmlElt.offsetTop;
				if (isNS6)return t;
				var parent=htmlElt.parentNode;
				var previous=htmlElt;
				while (parent.offsetTop){
						//Don't calculate the position twice
						//For example if my element is a TD, 
						//the offsetTop of TD is the same of the offsetTop of TR
						if (previous.offsetTop!=parent.offsetTop){
								t +=parent.offsetTop;
								previous=parent;
							}
						parent=parent.parentNode;
					}
				return t;
				break; 
		} 
	}
///<summary>
///Encode the value for the url
///</summary>
function urlEncode(text){
    if (text ==null || text == undefined)return "";
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" +					// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"éèêëïîàçùüû" +
					"-_.!~*'()";					// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";
	var encoded = "";
	var strText=text + ""; //Force to text format
	var i=0;
	while ( i < strText.length){
		var ch = strText.charAt(i);
	    if (ch == " ") {
		    encoded += "+";				// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch;
		} else {
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
			    /*alert( "Unicode Character '" 
                        + ch 
                        + "' cannot be encoded using standard URL encoding.\n" +
				          "(URL encoding only supports 8-bit characters.)\n" +
						  "A space (+) will be substituted." );
				encoded += "+";*/
				encoded +=ch; //Change by Askia (keep the character)
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
        i++;
	} // while
	return encoded;
}

///<summary>
///Decode the value from the url
///</summary>
function urlDecode(text){
    if (text ==null || text == undefined)return "";
    
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef"; 
   var decoded = "";
   var i = 0;
   var strText=text +""; //Force to text
   while (i < strText.length) {
       var ch = strText.charAt(i);
	   if (ch == "+") {
	       decoded += " ";
		   i++;
	   } else if (ch == "%") {
			if (i < (strText.length-2) 
					&& HEXCHARS.indexOf(strText.charAt(i+1)) != -1 
					&& HEXCHARS.indexOf(strText.charAt(i+2)) != -1 ) {
				decoded  += unescape( strText.substr(i,3) );
				i += 3;
			} else {
				//alert( 'Bad escape combination near ...' + encoded.substr(i) );
				decoded += ch;//"%[ERROR]";
				i++;
			}
		} else {
		   decoded += ch;
		   i++;
		}
	} // while
   return decoded;
}