/**
 * Basis JS-Funktionalitaeten
 */
var AwppiBase = function()
{
	/**
	 * Schaltet die Sichtbarkeit eines DIVs von none nach block und zurueck um
	 * 
	 * @param string		id
	 * 
	 * @return void
	 */
	this.toggleVisibility = function(id)
	{
		var obj, newState;
		
		if(!(obj = document.getElementById(id))) {
			return;
		}
		
		
		if((obj.style.display == 'none') || !obj.style.display) {
			newState = 'block';
		} else {
			newState = 'none';
		}
		
		obj.style.display = newState;
		
		return;
	};
	
	
	/**
	 * OnLoad-Action, prueft ob es ein Element mit dem Namen 'idFormsubmited' gibt
	 * Wenn ja, wird das Value des Elements als ID des Elements interpretiert
	 * dessen display auf block gesetzt werden soll.
	 * Was soll das alles? 
	 * Dadurch wird bei ein/ausblendbaren oder mehrere Formularen auf einer
	 * HTML-Seite ermöglicht das das abgesendete Formular eingebelnedt wird
	 */
	this.multiFormOnLoad = function(txt)
	{
		var arr, id, ob;
		
		arr = document.getElementsByName('idFormSubmited');
		if(arr.length == 0) {
			return;
		}
		
		id = arr[0].value;
		
		if(!(obj = document.getElementById(id))) {
			return;
		}
		
		obj.style.display = 'block';
		
		document.location.href = '#' + id;
	}
};


/**
 * Object als assoziatives Array
 */
function AssocArray() 
{
   // Array der gesetzen Keys
   this.keySet = new Array();

   /**
    * Setzt die Eigenschaft key mit dem Wert value
    * und speichert welcher Wert gesetzt wurde
    *
    * @param string  key
    * @param mixed   value
    *
    * @return void
    */
   this.set = function(key, value)
   {
      var idx;

      // Wert setzen
      this[key] = value;

      // wurde der Key schon gespeichert
      for(idx = 0; idx < this.keySet.length; idx++)
      {
         if(this.keySet[idx] == key)
         {
            // ja
            return;
         }
      }

      this.keySet.push(key);
   };
};


/**
 * Basisfunktionalitaeten
 * 
 */
var Site = function(){
	
	this.xhr         = false;
	this.xhrIdOutput = false;
	
	/** 
	 * Sends a xmlHttpRequest
	 *
	 */
	this.simpleXmlHttpRequest = function(url, idOutput, arrParameter, callBackMethod){
		this.xhr = false;
		
		if(!arrParameter){
			arrParameter = new Array();
		}
		
		// Damit der SimpleXml-Kontext-Switch im Zend Framework ausgefuehrt wird
		arrParameter.push('format=simpleXmlHttp');		
		
		// try to create a xmlHttpRequest-Object
		// Mozilla, Opera, Safari or Internet Explorer 7
		if ( typeof XMLHttpRequest != 'undefined') {
		    this.xhr = new XMLHttpRequest();
		}
	
		if ( !this.xhr) {
		    // Internet Explorer 6 or older
		    try {
		        this.xhr  = new ActiveXObject("Msxml2.XMLHTTP");
		    } catch(e) {
		        try {
		            this.xhr  = new ActiveXObject("Microsoft.XMLHTTP");
		        } catch(e) {
		            this.xhr  = false;
		        }
		    }
		}
	
		if(!this.xhr){
			// creation of the xmlHttpReq-Object failed
			alert('Creation of the xmlHttpRequest-Object failed.');
			return false;
		}
		
		// 
		if((objOutput = document.getElementById(idOutput))){
			objOutput.innerHTML = '<div style="filter:Alpha(opacity=50); opacity: 0.5; -khtml-opacity: 0.5; cursor:wait;">'
				                 + objOutput.innerHTML
				                 + '</div>';
		}
		
		// send the request 
		try {
			this.xhr.idOutput = idOutput;	
			this.xhrIdOutput  = idOutput;
		} catch (e) {
			// TODO: handl
			this.xhrIdOutput = idOutput;
		}
		
		
		this.xhr.open('POST', url, true);
		
		if(!callBackMethod){
			this.xhr.onreadystatechange = this.display;
		} else{
			this.xhr.onreadystatechange = callBackMethod;
		}
		
		this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		this.xhr.setRequestHeader('X_REQUESTED_WITH', 'XMLHttpRequest');
		this.xhr.send(this.urlCodeParaArray(arrParameter));
	
		return true;
	};
	
	
	/**
	 * Default Call-back Method for the xmlHttpRequest
	 *
	 */
	this.display = function(){
		var objDivOutput = false;
		
		if(objSite.xhr.readyState == 4) {	
			if(!(objDivOutput = document.getElementById(objSite.xhrIdOutput))){
				alert('xmlHttpRequest failed. Can\'t get div: output id = ' + objSite.xhrIdOutput);
				return false;
			}
			
			if(objSite.xhr.status == 200) {
				if(!objSite.xhr.responseText) {
					alert('xmlHttpRequest failed. status != 200');
					return false;			
				}
				
				objDivOutput.innerHTML = objSite.xhr.responseText;
				return true;
			} else{
				// Print the error message
				objDivOutput.innerHTML = String(objSite.xhr.responseText);
				//alert('== 4 stat = ' + objSite.xhr.status + ' - ' + objSite.xhr.responseText);
			}
		} // END xmlHttpReq.readyState == 4
		
		return false;
	};
	
	
	/**
	 * Ausgabe eines "Bitte warten"-Hinweises
	 * 
	 * @TODO Auswahl der Wartessymbole ermoeglichen
	 * 
	 * @param string		idDiv
	 * @param string		type
	 * 
	 * @return bool
	 */
	this.setWait = function(idDiv, type)
	{
		var obj, strHtmlCode;
		
		if(!(obj = document.getElementById(idDiv))) {
			return false;
		}
		
		strHtmlCode = '<table width="100%" height="100%">'
				    + '<tr>'
				    + '<td align="center" valign="middle">'
				    + '<img src="/common/img/wait_bw_16_16.gif" widht="16" height="16" alt="Bitte warten" />'
				    + '</td></tr></table>';
		
		obj.innerHTML = strHtmlCode;
		
		return true;
	}
	
	
	this.urlCodeParaArray = function(arrIn)
	{
	   var i, parts, fieldName, fieldValue;
	   var strCoded = '';
	   var arrOut   = new Array();

	   for(i = 0; i < arrIn.length; i++)
	   {
	      parts = arrIn[i].split('=');

	      fieldName = parts[0];
	      parts.shift();
	      fieldValue = this.urlencode(parts.join('='));

	      arrOut.push(fieldName + '=' + fieldValue);
	   }

	   return arrOut.join('&');
	};
	
	
	this.urlencode = function(str)
	{
	    // http://kevin.vanzonneveld.net
	    // +   original by: Philip Peterson
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: AJ
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // %          note: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
	    // *     example 1: urlencode('Kevin van Zonneveld!');
	    // *     returns 1: 'Kevin+van+Zonneveld%21'
	    // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
	    // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
	    // *     example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
	    // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'

	    var histogram = {}, histogram_r = {}, code = 0, tmp_arr = [];
	    var ret = str.toString();
	    var i;

	    // The histogram is identical to the one in urldecode.
	    histogram['!']   = '%21';
	    histogram['%20'] = '+';

	    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
	    ret = encodeURIComponent(ret);
		
		// f++king IE!
//	    for(search in histogram)
		for(i = 0; i < histogram.length; i++)
	    {
	        replace = histogram[i];
	        tmp_arr = ret.split(i); // Custom replace
	        ret = tmp_arr.join(replace);
	    }

	    // Uppercase for full PHP compatibility
	    return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2)
	    {
	        return "%"+m2.toUpperCase();
	    });

	    return ret;
	};
	
	
	/**
	 * Prueft einen Datumsstring auf Gueltigkeit
	 * 
	 * @param string	strDate			Das Datum
	 * @param string	locale			Locale des Datumsstring (z.Z werden nur 
	 * 									die deusche und die amerikanische 
	 * 									Formatierung unterstuetz)
	 * 
	 * @return bool
	 */
	this.checkDate = function(strDate, locale)
	{
		var p, parts, i, delim, reg, pSort;
		
		switch(locale) {
			case 'de':
				delim = '.';
				reg   = /^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$/
				pSort = new Array(2, 1, 0);
			break;
			
			case 'en':
				delim = '-';
				reg   = /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/;
				pSort = new Array(0, 1, 2);
			break;
			
			default:
				alert('Site.checkDate: locale must be de or en');
				return false;
		}
		
		if(!strDate.match(reg)) {
			return false;
		}
		
		// in die Bestandteile spliten und in der amerikanische Reihenfolge
		// in das Array parts packen (Jahr, Monat, Tag)
		parts = new Array();
		p = strDate.split(delim);
		
		for(i = 0; i < 3; i++) {
			parts[i] = p[pSort[i]];
		}
		
		// bei Monat und Tag fuehrende Nullen loesche
		parts[0] = parts[0].replace(/^0/, '');
		parts[1] = parts[1].replace(/^0/, '');
		
		// Datum auf Gueltigkeit pruefen
		// Jahr zwischen 1970 und 2050
		if((parseInt(parts[0]) < 1970) || (parseInt(parts[0]) > 2050)) {
			alert(1);
			return false;
		}
		
		// Monat zwischen 1 und 12
		if((parseInt(parts[1]) < 1) || (parseInt(parts[1]) > 12)) {
			alert('M = ' + parseInt(parts[1]));
			return false;
		}
		
		// Tag zwischen 1 und 31
		if((parseInt(parts[2]) < 1) || (parseInt(parts[2]) > 31)) {
			alert(3);
			return false;
		}
		
		// TODO pruefen ob es das Datum ueberhaupt gibt
		
		return true;
	};
	
	
	/**
	 * Wandelt einen Datumsstring in eine Unix-Timestamp
	 * 
	 * @param string	strDate
	 * @param string	locale			Locale des Datumsstring (z.Z werden nur 
	 * 									die deusche und die amerikanische 
	 * 									Formatierung unterstuetz)
	 * 
	 * @return int
	 */
	this.dateToTimestamp = function(strDate, locale)
	{
		var p, parts, i, delim, pSort, objDate;
		
		switch(locale) {
			case 'de':
				delim = '.';
				pSort = new Array(2, 1, 0);
			break;
			
			case 'en':
				delim = '-';
				pSort = new Array(0, 1, 2);
			break;
			
			default:
				alert('Site.checkDate: locale must be de or en');
				return false;
		}
		
		// in die Bestandteile spliten und in der amerikanische Reihenfolge
		// in das Array parts packen (Jahr, Monat, Tag)
		parts = new Array();
		p = strDate.split(delim);
		
		for(i = 0; i < 3; i++) {
			parts[i] = p[pSort[i]];
		}
		
		objDate= new Date(parts[0], parts[1], parts[2]);
		
		return objDate.getTime() * 1000;
	};
	
	
	/**
	 * 
	 */
	this.inputCharCount = function(objEv, ev, maxCharCount)
	{
		var idOut, objOut, actCharCount, cursorPos;
		
		// Anzahl der Zeichen im Input-Element 
		actCharCount = objEv.value.length;
		
		// Wenn die Eingabe zu lang ist, ueberzaehlige Zeichen abschneiden
		if(actCharCount > maxCharCount) {
			// TODO Im IE testen
			cursorPos = objEv.selectionStart;
			
			objEv.value  = objEv.value.substring(0, maxCharCount);
			actCharCount = maxCharCount;
			
			objEv.selectionStart = cursorPos;
			objEv.selectionEnd   = cursorPos;
			
		}
		
		// Ausgabe der Zeichenanzahl
		idOut = 'inputCharCount_' + objEv.id;
		
		if(!(objOut = document.getElementById(idOut))) {
			alert('Can\'t get DIV, id =  ' + idOut);
			return;
		}
		
		objOut.innerHTML = actCharCount + ' von ' + maxCharCount + ' Zeichen';
		return;
	}
	
	
	/**
	 * ucfirst. Wandelt den ersten Buchstaben des Strings in einen Grossbuchstaben
	 * 
	 * @param string
	 * 
	 * @return string
	 */
	this.ucfirst = function(strIn)
	{
		if(typeof strIn != 'string') {
			return strIn;
		}
		
		return strIn.substr(0, 1).toUpperCase() + strIn.substr(1);
	}
	
	
	/**
	 * Liefert das Value des idx ten Auftretens des XML-Tags tagName in objXml
	 * 
	 * @param XML-Object		objXml			XML-Dokument
	 * @param string			tagName
	 * @param int				idx
	 */
	this.getXmlTagValue = function(objXml, tagName, idx)
	{
		var arrErg;
		
		if(!idx) {
			idx = 0;
		}
		
		if(!(arrErg = objXml.getElementsByTagName(tagName))) {
			// Tag nicht gefunden
			return;
		}
		
		if(arrErg.length < (idx + 1)) {
			// der Tag ist nicht oft genug vorhanden 
			return '';
		}
		
		return arrErg[idx].firstChild.nodeValue;
	};
	
	
	/**
	 * Liefert ein Array der ausgewaehlten Values des Selects mit der ID idSelect
	 * 
	 * @param string		idSelect
	 * 
	 * @return Array 
	 */
	this.getSelectedValues = function(idSelect)
	{
		var obj, i;
		var arrVal = new Array();
		
		if(!(obj = document.getElementById(idSelect))) {
			alert("Can't get element. id = " + idSelect);
			return arrVal;
		}
		
		if(!obj.options) {
			// kein Select
			return arrVal;
		}
		for(i = 0; i < obj.options.length; i++) {

			if(obj.options[i].selected) {
				arrVal.push(obj.options[i].value);
			}
		}
		
		return arrVal;
	};
	
	
	/**
	 * Ermittelt die Groesse des Browserfesnsters und liefert diese als Array
	 * Index 0 = Breite
	 * Index 1 = Hoehe
	 * 
	 * @param void
	 * 
	 * @return Array
	 */
	this.getWindowSize = function()
	{
		var arrSize = new Array();
		
		try{
			arrSize[0] = window.innerWidth;
			arrSize[1] = window.innerHeight;
		} catch(e) {
			// f**king IEs
			arrSize[0] = document.body.clientWidth;
			arrSize[1] = document.body.clientHeight;
		}
		
		if(arrSize[0] == undefined){
			// f**king IEs
			arrSize[0] = document.documentElement.clientWidth;
			arrSize[1] = document.documentElement.clientHeight;
		}
		
		return arrSize;
	};
	
};

var objSite      = new Site();
var objAwppiBase = new AwppiBase();

