/**
 * Javascript Functions and extension
 * Here you can find extension lib which interact directly or indirectly whith prototype.js fremework
 * @see Prototype
 * 
 * @requires package Prototype (all classes)
 * 
 * @author Lino Telera (collected by)
 *
**/

/**
 * Global vars inside 
 */
var g_fPrototypeFunctionEval = eval; // Global evaluation function

var PrototypeFunction = {
	sAuthor: 'Lino "Jan" Telera',
  	sVersion: '1.0'
}




/**
 * Extension gets element by attribute
 * @param {Object} oElm
 * @param {Object} strTagName
 * @param {Object} strAttributeName
 * @param {Object} strAttributeValue
 */
Element.getElementsByAttribute= function(oElm, strTagName, strAttributeName, strAttributeValue){
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    var oAttributeValue = (typeof strAttributeValue != "undefined")? new RegExp("(^|\\s)" + strAttributeValue + "(\\s|$)") : null;
    var oCurrent;
    var oAttribute;
    for(var i=0; i<arrElements.length; i++){
        oCurrent = arrElements[i];
        oAttribute = oCurrent.getAttribute(strAttributeName);
        if(typeof oAttribute == "string" && oAttribute.length > 0){
            if(typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))){
                arrReturnElements.push(oCurrent);
            }
        }
    }
    return arrReturnElements;
}


/**
 * Array splice
 */
if(!Array.prototype.splice) {
    
	
	Array.prototype.splice = function(iStart, iLength) {
        
		
		
		if(iLength < 0) iLength = 0;

        var aInsert = new Array();
        if(arguments.length > 2) {
            for(var i=2; i<arguments.length; i++) {
                aInsert.push(arguments[i]);
            }
        }
    
        var aHead = this.subarray(0, iStart);
        var aDelete = this.subarr(iStart, iLength);
        var aTail = this.subarray(iStart + iLength);
    
        var aNew = aHead.concat(aInsert, aTail);
    
        // Rebuild yourself
        this.length = 0;
        for(var i=0; i<aNew.length; i++) {
            this.push(aNew[i]);
        }
    
        return aDelete;
    }
}



/**
 * Static Class
 * Include file js, css, img, ...
 */
var Include = {
	
	sFileIncluding:null,
	
	sHtmlInclude: '',
	
	/**
	 * Include and eval js code via xmlhttp sync call
	 * @param String input file ti include
	 * @param boolean bAsync if true call asyncr
	 * @param Object cb function to call only in async mode
	 * @return String js file content to eval (you must eval out of there only for IE and Opera)
	 */
	js: function(sInputFile, bASync, oCbFunction){
		if (PrototypeFunction.Loading)
			PrototypeFunction.Loading.show("Loading " +sInputFile );
			
		Include.sFileIncluding = sInputFile;
		
		if (!bASync){
			bASync = false;
		}
	
		if (bASync){
			oCall = new Ajax.Request(sInputFile+'?'+Math.random(),{
				asynchronous: true,
				method: 'get',
				mimetype: 'text/javascript',
				onSuccess: function(obj){
					
					if (Prototype.Browser.IE){
						if (PrototypeFunction.Loading)
							PrototypeFunction.Loading.hide();
						try{
							window.execScript (obj.responseText);
							Include.sFileIncluding = null;
						}catch(e){
							Log.write('Error including file '+Include.sFileIncluding+ ', Reason: '+ e);
							Include.sFileIncluding = null;
						}
						
						
						// Exec cb function	
						eval (oCbFunction(obj.responseText));
						return ;
						
						
					}else if (Prototype.Browser.Opera){
						if (PrototypeFunction.Loading)
							PrototypeFunction.Loading.hide();
						
						// Exec cb function	
						eval (oCbFunction(obj.responseText));
						
						return;
					}else{
						
						try{
							g_fPrototypeFunctionEval(obj.responseText);
							Include.sFileIncluding = null;
						}catch(e){
							Log.write('Error including file '+Include.sFileIncluding+ ', Reason: '+ e);
							Include.sFileIncluding = null;
							
						}
						
						Include.sFileIncluding = null;
						if (PrototypeFunction.Loading)
							PrototypeFunction.Loading.hide();
						
						
						// Exec cb function	
						eval (oCbFunction(obj.responseText));
						return ;
						
						
					}
									
				}
			});
		}else{ // Sync mode
			oCall = new Ajax.Request(sInputFile+'?'+Math.random(),{
				asynchronous: false,
				method: 'get',
				mimetype: 'text/javascript',
				onComplete: function(obj){
					
					if (Prototype.Browser.IE){
						if (PrototypeFunction.Loading)
							PrototypeFunction.Loading.hide();
						try{
							window.execScript (obj.responseText);
							Include.sFileIncluding = null;
						}catch(e){
							Log.write('Error including file '+Include.sFileIncluding+ ', Reason: '+ e);
							Include.sFileIncluding = null;
						}
						return oCall.transport.responseText;
						
					}else if (Prototype.Browser.Opera){
						if (PrototypeFunction.Loading)
							PrototypeFunction.Loading.hide();
						return oCall.transport.responseText;
					}else{
						
						Include.sFileIncluding = null;
						if (PrototypeFunction.Loading)
							PrototypeFunction.Loading.hide();
						try{
							g_fPrototypeFunctionEval(obj.responseText);
							Include.sFileIncluding = null;
						}catch(e){
							Log.write('Error including file '+Include.sFileIncluding+ ', Reason: '+ e);
							Include.sFileIncluding = null;
							
						}
						
						return oCall.transport.responseText;
					}
									
				}
			});
		}
		
		
		
		
		
	},
	
	js_static: function(sInputFile){
		var elLink = document.createElement("script");
		elLink.setAttribute("language","javascript");
		elLink.setAttribute("src",sInputFile);
			
			
		var elHead = document.getElementsByTagName("head")[0];
		elHead.appendChild(elLink);
	},
	
	/**
	 * Insert html code into el and return String html
	 * @param String Input file
	 * @param el Html to append html code
	 * @return String html code 
	 */
	html: function(sInputFile, elHtmlToAppend, oCbFunction){
		
		Include.sFileIncluding = "";
		
		oCall = new Ajax.Request(sInputFile+'?'+Math.random(),{
			asynchronous: false,
			method: 'get',
			onSuccess: function(obj){
				
				if (elHtmlToAppend != undefined && elHtmlToAppend != null){
					elHtmlToAppend.innerHTML += obj.responseText;
				}				
				Include.sFileIncluding = obj.responseText;
				
				//Try exec cb function
				if (oCbFunction){
					eval (oCbFunction());
				}
			}
		});
	},
	
	css: function(sInputFile, bLink){
		
		if (bLink){
			
			var elLink = document.createElement("link");
			elLink.setAttribute("type","text/css");
			elLink.setAttribute("rel","stylesheet");
			elLink.setAttribute("href",sInputFile);
			
			
			var elHead = document.getElementsByTagName("head")[0];
			elHead.appendChild(elLink);
		}else{
			oCall = new Ajax.Request(sInputFile+'?'+Math.random(),{
				asynchronous: false,
				method: 'get',
				mimetype: 'text/css',
				onComplete: function(obj){
					
					var elStyle = document.createElement("style");
					elStyle.setAttribute("type","text/css");
					elStyle.innerHTML = obj.responseText;
					
					
					var elHead = document.getElementsByTagName("head")[0];
					elHead.appendChild(elStyle);
						
				}
			});
		}
	}
}




/**
 * Static Class
 * NAME SPACE MANAGER
 * Keep naming convention behind Classes and directory 
 */
var g_sPrototypeFunctionBaseNameSpace = "";
var g_sPrototypeFunctionBaseDir = "";

var g_aPrototypeFunctionDir = new Array();
var g_aPrototypeFunctionClassNameSpace = new Array();
var g_aPrototypeFunctionGlobalVar = new Array();

var NameSpace ={
	
	/**
	 * Set base NameSpace
	 * @param String Base Name space
	 * @return void
	 */
	setBase : function(sBaseNameSpace){
		g_sPrototypeFunctionBaseNameSpace = sBaseNameSpace;	
	},
	
	/**
	 * Store namespace class information
	 * @param String Name of the class
	 * @param String Namespace used for class
	 * @return void; 
	 */
	register: function(sClassName, sNameSpace){
		
		g_aPrototypeFunctionClassNameSpace[sClassName] = sNameSpace;
	},
	
	/**
	 * Set Base dir
	 * @param String Base dir
	 * @return void;
	 */
	setBaseDir: function(sBaseDir){
		g_sPrototypeFunctionBaseDir = sBaseDir;
	},
	
	/**
	 * Get base directory application
	 * @retrun String base directory app
	 */
	getBaseDir: function(){
		return g_sPrototypeFunctionBaseDir;
	},
	
	/**
	 * Sets dir to global registry
	 * @param String Reg Name
	 * @param String Directory
	 * @return void
	 */
	setDir: function(sRegName, sDir){
		g_aPrototypeFunctionDir[sRegName] = sDir;
	},
	
	/**
	 * Get dir path given a Reg name
	 * @param String Reg Name
	 * @retrun String if all is well or return empty String
	 */
	getDir: function(sRegName){
		if (g_aPrototypeFunctionDir[sRegName] != undefined){
			return g_aPrototypeFunctionDir[sRegName]; 
		}else{
			return "";
		}
	},
	
	/**
	 * Store a var into global registry
	 * @param String Reg Name
	 * @param Object (can be String,int,... ) to store
	 * @return void 
	 */
	setGlobal: function(sRegName, oVar){
		g_aPrototypeFunctionGlobalVar[sRegName] = oVar;
	},
	
	/**
	 * Get var stored into global registry
	 * @param String Reg Name
	 * @return Object stored null if doesn't exists
	 */
	getGlobal: function(sRegName){
		if (g_aPrototypeFunctionGlobalVar[sRegName] != undefined){
			return g_aPrototypeFunctionGlobalVar[sRegName]; 
		}else{
			return null;
		}
	},
	
	/**
	 * return name space
	 * @param String Name of the class
	 * @return String name space
	 */
	getNameSpace: function(sClassName){
		
		var sNameSpace;
		
		if (g_aPrototypeFunctionClassNameSpace[sClassName] != undefined){
			sNameSpace = g_aPrototypeFunctionClassNameSpace[sClassName];
			
			sNameSpace = sNameSpace.replace(/g\//, ".");
			
			sNameSpace = g_sPrototypeFunctionBaseNameSpace+'.'+sNameSpace;
		}else{
			sNameSpace = "";
		}
		
		return sNameSpace;
		
		
	},
	
	/**
	 * return class directory
	 * @param String Class Name
	 * @return String dir location
	 */
	getClassDir: function(sClassName){
		var sNameSpace;
		
		if (g_aPrototypeFunctionClassNameSpace[sClassName] != undefined){
			sDir = g_aPrototypeFunctionClassNameSpace[sClassName];
			
			sDir = sDir.replace(".", "/");
			
			
			
			sDir = g_sPrototypeFunctionBaseDir+'/'+sDir;
		}else{
			sDir = "";
		}
		
		return sDir;
	}
}

var g_aPrototypeWidget = new Array();
var g_iPrototypeWidget = 0;

var Widget ={
	
	/***
	 * Register widget into array
	 * @param Object el
	 * @return int array index
	 */
	register: function(el, sId){
		g_aPrototypeWidget[g_iPrototypeWidget] = el;
		g_iPrototypeWidget++;
		
		
		return g_iPrototypeWidget - 1;
	},
	
	/**
	 * Get widget by givem index
	 * @param int iIndex
	 * @return Object 
	 */
	get: function(iIndex){
		return g_aPrototypeWidget[iIndex];
	}
}


/**
 * Static class... write all errors
 */
var Log = {
	
	/**
	 * Write error message
	 * @param String Error msg
	 * @return void
	 */
	write: function(sMsg){
		if (Prototype.Browser.Gecko){
			console.log(sMsg);
		}else{
			alert (sMsg);
		}
	},
	
	/**
	 * Fire up alert
	 * Override with Other components
	 * @param {Object} sMsg
	 */
	alert: function(sMsg){
		
		alert("WARNING " + sMsg);
	}
}



var LoadProtoExtension= {

	_iExtUi_part_loaded: 0,

	_oExtuiFunctionReady: null,
	_oExtuiClassReady:null,
	_sDir: null,
	
	sDirFramework: '',
	sDirApplication: '',

	/**
	 * Include all fw classes
	 * @param String sDir 
	 * @param boolean bAsync
	 * @param Object Call back function only when aSync == true
	 */
	all: function(sDir, bAsync, oCbFunction){
		
		if (sDir == "" && this.sDirFramework != ""){
			sDir = this.sDirFramework;
		}else{
			this.sDirFramework = sDir;	
		}
		
		
		
		
		
		if (bAsync == null){
			bAsync = false;
		}
		
		if (bAsync == false){
			// First include loading visual message for inclusion
			Include.js(sDir+'prototype.function.visual.loading.js');
			
			
			
			// Include scriptaculous // External scripts
			Include.js(sDir+'scriptaculous/scriptaculous.js'); // Main scriptaculous
			Include.js(sDir+'scriptaculous/effects.js'); 
			Include.js(sDir+'scriptaculous/controls.js'); 
			
			// Must include Window class
			
						
			// Include ajax extension and hisotry
			Include.js(sDir+'prototype.function.ajax.js');
			Include.js(sDir+'prototype.function.ajax.history.js');
			
			Include.js(sDir+'prototype.function.international.js');
			
			Include.js(sDir+'prototype.function.batch.js'); // Batch process
			
			Include.js(sDir+'prototype.function.math.js'); // Math conversion
			Include.js(sDir+'prototype.function.geom.js'); // Geometric function
			
			Include.js(sDir+'prototype.function.data.js'); // Data handling
			Include.js(sDir+'prototype.function.data.xml.js'); // Data handling
			
			// All visual classes
			Include.js(sDir+'prototype.function.visual.js');
			
			// Form element
			Include.js(sDir+'prototype.function.visual.form.js');
			Include.js(sDir+'prototype.function.visual.form.button.js');
			// Form element combobox
			Include.js(sDir+'prototype.function.visual.form.cbx.js');
			Include.js(sDir+'prototype.function.visual.form.cbx.font.js');
			Include.js(sDir+'prototype.function.visual.form.cbx.file.js');
			
			// Tab element
			Include.js(sDir+'prototype.function.visual.tab.js');
			
			// Table element
			Include.js(sDir+'prototype.function.visual.table.js');
	
			
			// Color picker
			Include.js(sDir+'prototype.function.visual.colorpicker.js');
			
			// Visual tree
			Include.js(sDir+'prototype.function.visual.tree.js');
			
			// Tooltip
			
			Include.js(sDir+'prototype.function.visual.tooltip.js');
			Include.js(sDir+'prototype.function.visual.toptip.js');
			
			Include.js(sDir+'prototype.function.player.js');
			
		}else{
			// First include Batch and Visual
			if (PrototypeFunction.Batch == null){
				Include.js(sDir+'prototype.function.visual.loading.js');
				Include.js(sDir+'prototype.function.batch.js');
			}
			
			PrototypeFunction.Batch.Include.addFile(sDir+'scriptaculous/scriptaculous.js');
			PrototypeFunction.Batch.Include.addFile(sDir+'scriptaculous/effects.js'); 
			PrototypeFunction.Batch.Include.addFile(sDir+'scriptaculous/controls.js'); 
			
			// Must include Window class
			
			// Include ajax extension and hisotry
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.ajax.js');
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.ajax.history.js');
			
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.international.js');
			
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.math.js'); // Math conversion
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.geom.js'); // Geometric function
			
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.data.js'); // Data handling
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.data.xml.js'); // Data handling
			
			// All visual classes
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.js');
			
			// Form element
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.form.js');
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.form.button.js');
			// Form element combobox
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.form.cbx.js');
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.form.cbx.font.js');
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.form.cbx.file.js');
	
	
			// Tab element
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.tab.js');
			
			// Table element
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.table.js');
			
			// Color picker
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.colorpicker.js');
			
			// Visual tree
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.tree.js');
			
			// Tooltip
			
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.tooltip.js');
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.visual.toptip.js');
			
			PrototypeFunction.Batch.Include.addFile(sDir+'prototype.function.player.js');
			
			PrototypeFunction.Batch.Include.startExec(oCbFunction);
		}
				
	},
	
	/**
	 * Include all extui with prototype adapter
	 * @param String starting dir
	 * @param Object function to call when all is ready
	 */
	extui: function(sDir,oClassReady, oFunctOnReady){ // Include only via aSync call
		
		if (sDir == "" && this.sDirFramework != ""){
			sDir = this.sDirFramework;
		}else{
			this.sDirFramework = sDir;	
		}
		
		this._oExtuiFunctionReady = null;
		this._oExtuiClassReady = null;
		this._sDir = null;
		sDirExtui = 'extyui/';
		sDirExtuiTheme = 'prototype-resources/resources/';
		this._oExtuiFunctionReady = oFunctOnReady;
		this._oExtuiClassReady = oClassReady;
		
		this._sDir = sDir;
	
		// Starts include css style
		Include.css(sDir+sDirExtuiTheme+'css/ext-all.css', true);
		Include.css(sDir+sDirExtuiTheme+'css/xtheme-aero.css', true);
			
		//PrototypeFunction.Batch.Include.addFile(sDir+sDirExtui+'adapter/prototype/ext-prototype-adapter.js');
		//PrototypeFunction.Batch.Include.addFile(sDir+sDirExtui+'ext.js');
		
		//PrototypeFunction.Batch.Include.startExec(this._loaded_extui.bind(this));
		
		/*Include.js(sDir+sDirExtui+'adapter/prototype/ext-prototype-adapter.js');
		Include.js(sDir+sDirExtui+'ext-all.js');*/
		
		Include.js_static(sDir+sDirExtui+'ext.js');
		
		//this._loaded_extui();
		
	},
	
	/**
	 * Loading application framework
	 * @param {Object} sDir
	 * @param {Object} bAsync
	 * @param {Object} oCbFunction
	 */
	applicationFw: function(sDir, bAsync, oCbFunction){
		
		
		
		if (sDir == "" && this.sDirFramework != ""){
			sDir = this.sDirFramework;
		}else{
			this.sDirFramework = sDir;	
		}
		
		var sDirAppFw = "application/";
		this.sDirApplication = sDir + sDirAppFw;
		
		if (bAsync == null){
			bAsync = false;
		}
		
		try{
			if (PrototypeData == null){
				Include.js(sDir+'prototype.function.data.js'); // Data handling
				Include.js(sDir+'prototype.function.data.xml.js'); // Data handling
			}
			if (PrototypeVisual == null){
				Include.js(sDir+'prototype.function.visual.js'); // Data handling
				Include.js(sDir+'prototype.function.visual.tab.js'); // Data handling
			}
		}catch(e){
			Include.js(sDir+'prototype.function.data.js'); // Data handling
			Include.js(sDir+'prototype.function.data.xml.js'); // Data handling
			Include.js(sDir+'prototype.function.visual.js'); // Data handling
			Include.js(sDir+'prototype.function.visual.tab.js'); // Data handling
			Include.js(sDir+'prototype.function.math.js');
		}
		
		if (bAsync == false){
			Include.js(this.sDirApplication+'prototype.application.js');
			Include.js(this.sDirApplication+'prototype.application.data.js');
			Include.js(this.sDirApplication+'prototype.application.page.js');
			Include.js(this.sDirApplication+'prototype.application.page.layout.js');
			Include.js(this.sDirApplication+'prototype.application.page.layout.item.js');
			Include.js(this.sDirApplication+'prototype.application.page.layout.tab.js');
			Include.js(this.sDirApplication+'prototype.application.page.layout.stdmodule.js');
			Include.js(this.sDirApplication+'prototype.application.page.layout.item.module.js');
			Include.js(this.sDirApplication+'prototype.application.page.layout.item.tab.js');
			
			
			
			// Include Base Class
			
		}else{
			if (PrototypeFunction.Batch == null){
				Include.js(sDir+'prototype.function.visual.loading.js');
				Include.js(sDir+'prototype.function.batch.js');
			}
			
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.data.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.layout.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.layout.item.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.layout.tab.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.layout.stdmodule.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.layout.item.module.js');
			PrototypeFunction.Batch.Include.addFile(this.sDirApplication+'prototype.application.page.layout.item.tab.js');
			
			
			PrototypeFunction.Batch.Include.startExec(oCbFunction);
		}
	},
	
	_loaded_extui: function(){
		eval ("this._oExtuiFunctionReady()");	
		
		/*if (this._oExtuiClassReady == null){
			eval ("this._oExtuiFunctionReady()");	
		}else{
			eval ('Ext.onReady('+this._oExtuiFunctionReady+', '+this._oExtuiClassReady+')');	
		}*/
		
		
	},
	
	
	loaded_extui: function(){
		
		return;
		sDirExtui = 'extyui/';
		
		this._iExtUi_part_loaded++;
		
		if (this._iExtUi_part_loaded == 1){
			Include.js_static('../lib/'+sDirExtui+'ext-all.js');
		}
		
		if (this._iExtUi_part_loaded == 2){
			eval ("this._oExtuiFunctionReady()");	
			/*if (this._oExtuiClassReady == null){
				
			}else{
				eval ('Ext.onReady('+this._oExtuiFunctionReady+', '+this._oExtuiClassReady+')');	
			}*/
		}
	}

}


