/**
 * Diese JavaScript Datei definiert allgemeine Funktionalitäten.
 * global: 
 *   - allgemeine erweiterte String-Operationen
 *   - allgemeine check routine zum Prüfung was ein Object ist
 * goUtils:
 *   - Hilfsfunktionen für Statistik: emitMessage() für ivw, misTracking() für mis
 *   - Hilfsfunktion für AdServer
 *   - Hilfsfunktion zum extra Window-Aufmachen (z.B. Hilfeseite, Druckseite): win.*()
 *   - Hilfsfunktionen für Layout: ein Layer (Suggest, Historie) wird (un)sichtbar gemacht, 
 *     abhängig von Input-Feldern positioniert. 
 *	 - Hilfsfunktionen für die Such-Blättern-Logik: alle append*()
 *   - Hilfsfunktionen für Helpboxes mittels ajax innerhalb des Schnellsuche-Maskes
 * goUrl:
 *   - allgemeine url-Behandlung
 * accordionEffect:
 *   - @zis/lso
 *
 * Bearbeiter: ych am 06.09.2009
 *
 * Bibliothek(en): jquery
 *
 */


/*********************      string utilitiy prototypes     ************************/

String.prototype.trim = function() {
	a = this.replace(/^\s+/, '');
	return a.replace(/\s+$/, '');
};

String.prototype.startsWith = function(str)
{return (this.match("^"+str)==str)}

String.prototype.endsWith = function(str)
{return (this.match(str+"$")==str)}

String.prototype.isNotEmpty = function()
{return ((this && this.length>0)?true:false)}

String.prototype.isEmpty = function()
{return (! this.isNotEmpty())}


/* Check format of a string
 * Examples:
 * if( !frm.DateField.value.isFormat("date") )			// date
 * if( !frm.TimeField.value.isFormat("time") )			// time
 * if( !frm.PhoneNumber.value.isFormat(/^\d{9}$/ ) ) 	// a number of 9 digits
 */
String.prototype.isFormat = function ( sType ) {
	var undef;
	var aTypes = new Array();
	aTypes['time'] = /^[0-2]?\d:[0-5]{1}\d/;
	aTypes['date'] = /^[0-3]?\d\/[0-1]?\d\/\d{4}/;
	aTypes['@unique'] = /^\D{4}-[\d|\D]{6}/;
	if ( isUndefined( aTypes[ sType ] ) ) {
		return sType.test( this );
	} else {
		return aTypes[ sType ].test( this );
	}
} 

/*********************      main check utilities     ************************/

function isUndefined (el) { return (typeof el == 'undefined');	}
function isDefined   (el) { return typeof el != 'undefined'; }
function isFunction  (el) { return typeof el == 'function'; }
function isNull      (el) { return typeof el == 'object' && !el; }
function isNumber    (el) { return typeof el == 'number' && isFinite(el); }
//function isNumber(x) {return ( (typeof x == typeof 1) && (null != x) && isFinite(x) )}
function isObject    (el) { return (el && typeof el == 'object') || isFunction(el);	}
function isString    (el) { return typeof el == 'string'; }
function isArray	 (el) { return isObject(el) && el.constructor == Array; }
function isUndefOrNull (el) { return (typeof el == 'undefined') || (typeof el == 'object' && !el) };
function objIsInstanceOf (obj, classObj) {
	while (obj.__proto__) {
		if (obj.__proto__ === classObj) {
			return true;				
		}
		obj = obj.__proto__;			
	}
	return false;		
}

/*********************      goyellow utilities     ************************/

// take care of firebug console logging for other browsers
//var console = window.console || {};
//console.log = console.log || function(t) { }; 

// Utilities Class
function Utilities(){
	//this.lastIvwMessage = new Date().getTime() / 1000;
	this.trace = function(sString, oLayer){
		if(isObject(this.getDom(oLayer))){
			this.getDom(oLayer).innerHTML += "<br>--------------------------------------------<br>" + sString;
		} else if(isObject(this.getDom("debugWrapper"))){
			this.getDom("debugWrapper").innerHTML += "<br>--------------------------------------------<br>" + sString; 
		} else {
			var oDebug = document.createElement("div");
			oDebug.id = "debugWrapper";
			oDebug.className = "debugWrapper";
			oDebug.innerHTML = "<br>--------------------------------------------<br>" + sString;
			document.body.appendChild(oDebug);			
		}
	};

	// IVW-Tag
	this.emitMessage = function(sAction) {
   		var ivwImage = new Image();
   		ivwImage.src = "http://goyellow.ivwbox.de/cgi-bin/ivw/CP/" + sAction + "?r="+escape(document.referrer)+"&d="+(Math.random()*100000);
       	ivwImage = null;
   			
    };
	
	// MIS tracking
	this.misTracking = function(args){
  		var misImage = new Image();
   		misImage.src = "/tracking.jsp?" + args;
	}
	
	// AdServer -- wird auch direkt vom AdServer aus aufgerufen -- Interface stabil halten
	this.callAdServer = function(zoneId, selectionString) {
   		var m3_r = Math.floor(Math.random()*99999999999);
     
   		document.write ("<scr"+"ipt type='text/javascript' src='http://www.goyellow.de/ox/www/delivery/ajs.php");
   		document.write ("?zoneid=" + zoneId + "&amp;source=zone" + zoneId + selectionString + "&amp;cb=" + m3_r);

   		if (!document.MAX_used) document.MAX_used = ','; 
   		if (document.MAX_used != ',') document.write ("&amp;exclude=" + document.MAX_used);
   		document.write (document.charset ? "&amp;charset="+document.charset : (document.characterSet ? "&amp;charset="+document.characterSet : ""));
   		document.write ("&amp;loc=" + escape(window.location));
   		if (document.referrer) document.write ("&amp;referer=" + escape(document.referrer));
   		if (document.context) document.write ("&context=" + escape(document.context));
   		if (document.mmm_fo) document.write ("&amp;mmm_fo=1");
   		document.write ("'><\/scr"+"ipt>");	
	};
	
	this.win = {
		openDefault: function(strURL, numWidth, numHeight, wName){
			(!numWidth) ? numWidth = "780" : 0;
			(!numHeight) ? numHeight = "600" : 0;
			var strWindowName = (wName) ? wName : "defaultWindow";
			var strWinProps = "width=" + numWidth + ",height=" + numHeight + ",titlebar=no,status=yes,toolbar=no,menubar=yes,scrollbars=yes,resizable=yes";
			this.open(strURL, strWindowName, strWinProps);
			return false;
		},
		// General function to open information windows
		// strURL = URL, numWidth = windowWidth, numHeight = windowHeight
		openInfo: function(strURL, numWidth, numHeight){
			var strWindowName = "infoWindow";
			var strWinProps = "width=" + numWidth + ",height=" + numHeight + ",titlebar=no,status=yes,toolbar=no,menubar=no,scrollbars=no,resizable=yes";
			this.open(strURL, strWindowName, strWinProps);
			return false;
		},
		open: function(strURL, strWindowName, strWinProps){
			var objWin = window.open(strURL, strWindowName, strWinProps);
			objWin.focus();
		}
	};

	this.setLyr = function(objId,lyr, dx, dy, offset){
		if (! objId) return;
		var obj = $("#"+objId);
		if (! obj) return;
		
		if (! lyr) return;
		var lyrObj = lyr;
		if (isString(lyr)) { lyrObj = $("#"+lyr) }; 
		
		if (! offset ) offset = 0;
		var newX = this.findPosX(obj[0]);
		var newY = this.findPosY(obj[0]);
		lyrObj.css({"top" : ((newY+dy) + 'px'), "left" : ((newX+dx+offset) + 'px')});
	};
	
	// Get x-positon of object
	this.findPosX = function(obj){
		var curleft = 0;
		if (obj.offsetParent){
			while (obj.offsetParent){
				curleft += obj.offsetLeft;
				obj = obj.offsetParent;
			}
		}
		else if (obj.x)	curleft += obj.x;
		return curleft;
	};
	// Get y-position of object
	this.findPosY = function(obj){
		var curtop = 0;
		if (obj.offsetParent)	{
			while (obj.offsetParent){
				curtop += obj.offsetTop;
				obj = obj.offsetParent;
			}
		}
		else if (obj.y)	curtop += obj.y;
		return curtop;
	};

	// Hide Element (visibility) -- deprecated 
	this.hideElement = function(strElementName){
		$("#"+strElementName).css(this.css.invisible);
	};

	this.css = {
		visible :  {"visibility" : "visible", "display" : "block" },
		invisible: {"visibility" : "hidden", "display" : "none"  },
		colorEnable:  {"color" : "#555555", "background-color" : "#ffffff"},
		colorDisable: {"color" : "#666666", "background-color" : "#cccccc"}
	};	
	// Disable and enable elements
	this.disableElement = function(strElementID){		
		$("#"+strElementID).css(this.css.colorDisable).attr("disabled", true);
	};
	this.enableElement = function(strElementID){
		$("#"+strElementID).css(this.css.colorEnable).attr("disabled", false);
	};
	
	// Schnellsuche	
	this.append = function(obj, nof, max, mdn, loc, ord) {

		var strHref = obj.getAttribute("href");
		var strQry = "LSTPOS=" + nof + "&LSTAMT=" + max + "&MDN=" + mdn + "&LOC=" + loc + "&PNO=" + ord + "&REF=" + $.cookie('GY_LAYOUT');

		if (strHref.indexOf("\#") > 0) {
		  var pos = strHref.lastIndexOf("\#");
		  if (strHref.indexOf("?") > 0) {
		    location.href = strHref.substring(0,pos) + "&" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  } else {
		    location.href = strHref.substring(0,pos) + "?" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  }
		} else  if (strHref.indexOf(".html") > 0) {
		  location.href = strHref + "?" + strQry;
		} else {
	          location.href = strHref + "&" + strQry;
		}

		return false;
	};

	// Detailsuche	
	this.appendDet = function(obj, nof, max, giv, nam, pro, str, hno, zcd, loc, spc, noa, ord) {

		var strHref = obj.getAttribute("href");
		var strQry = "LSTPOS=" + nof + "&LSTAMT=" + max + "&GIV=" + giv + "&NAM=" + nam + "&PRO=" + pro +
					 "&STR=" + str + "&HNO=" + hno + "&ZCD=" + zcd + "&LOC=" + loc + 
					 "&SPC=" + spc + "&NOA=" + noa  + "&PNO=" + ord  + "&REF=" + $.cookie('GY_LAYOUT');

		if (strHref.indexOf("\#") > 0) {
		  var pos = strHref.lastIndexOf("\#");
		  if (strHref.indexOf("?") > 0) {
		    location.href = strHref.substring(0,pos) + "&" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  } else {
		    location.href = strHref.substring(0,pos) + "?" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  }
		} else  if (strHref.indexOf(".html") > 0) {
		  location.href = strHref + "?" + strQry;
		} else {
		  location.href = strHref + "&" + strQry;
		}

		return false;
	};

	// Inverssuche
	this.appendInv = function(obj, nof, max, tel) {

		var strHref = obj.getAttribute("href");
		var strQry = "LSTPOS=" + nof + "&LSTAMT=" + max + "&TEL=" + tel + "&REF=" + $.cookie('GY_LAYOUT');

		if (strHref.indexOf("\#") > 0) {
		  var pos = strHref.lastIndexOf("\#");
		  if (strHref.indexOf("?") > 0) {
		    location.href = strHref.substring(0,pos) + "&" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  } else {
		    location.href = strHref.substring(0,pos) + "?" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  }
		} else if (strHref.indexOf(".html") > 0) {
		  location.href = strHref + "?" + strQry;
		} else {
	          location.href = strHref + "&" + strQry;
		}

		return false;
	};

	// Notdienste
	this.appendEmg = function(obj, nof, max, bcp, loc, ord) {

		var strHref = obj.getAttribute("href");
		var strQry = "LSTPOS=" + nof + "&LSTAMT=" + max + "&BCP=" + bcp + "&LOC=" + loc + "&PNO=" + ord + "&REF=" + $.cookie('GY_LAYOUT');

		if (strHref.indexOf("\#") > 0) {
		  var pos = strHref.lastIndexOf("\#");
		  if (strHref.indexOf("?") > 0) {
		    location.href = strHref.substring(0,pos) + "&" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  } else {
		    location.href = strHref.substring(0,pos) + "?" + strQry + "#" + strHref.substring(pos+1,strHref.length);
		  }
		} else if (strHref.indexOf(".html") > 0) {
		  location.href = strHref + "?" + strQry;
		} else {
	          location.href = strHref + "&" + strQry;
		}

		return false;
	};
	
	// Helpboxes - für die Hilfe-Link unter den Suchfeldern in Suchmaske
	this.help = {
		show: function(sType, styleInfo, hText){
			
			if (sType == 'geoPortalUsage') { goUtils.emitMessage ('map_help'); }
			this.sHelpType = sType;
			this.headingText = hText;
			
			if (styleInfo.targetId) 
				this.sPosToNodeId = styleInfo.targetId;
			if (styleInfo.className) 
				this.className = styleInfo.className;
			var fncCallback = styleInfo.callback ? styleInfo.callback : 0;
			
			$(document.body).append('<div id="helpBoxWrapper" style="display:none;"></div>');
			
			$("#helpBoxWrapper").load("/helpdata/wrapper",
				function() { 
					goUtils.help.loadContent(fncCallback);
				}
			);
			this.setHandlers();
			return false;
		},
		setHandlers: function(){
			// Bind mouseup to remove layer. Store mouseUpEvent to remove specific event at removeHandlers()
			$(document.body).mouseup(goUtils.help.mouseUpEvent = function(event){ goUtils.help.handleMouseClick(event) } );
		},
		removeHandlers: function(){
			$(document.body).unbind("mouseup", goUtils.help.mouseUpEvent);
		},
		handleMouseClick: function(event){
			// Hide History if outside of histLayer
			$(event.target).parents("#helpBox").length <= 0 ? this.remove() : 0;
		},
		loadContent: function(fncCallback){
			$("#innerContentWrapper").load("/helpdata/" + this.sHelpType,
				function(){
					// Content has loaded - now adjust layer
					goUtils.help.adjust();
					// Call given function if any
					if(fncCallback) eval(fncCallback)();
				}
			);
		},
		adjust: function(){
			var refObj = $("#"+this.sPosToNodeId);
			var refClass = this.className;		
			var oLayer = $("#helpBox");
			
			if (refClass) oLayer.addClass(refClass);
			if (this.headingText) $("#helpHeading")[0].innerText = this.headingText;
					
			if (refObj) {				
				goUtils.setLyr(this.sPosToNodeId, "helpBox", 0, 30);
				$("#helpBoxWrapper").show();			
				//var sPosToNodeId = this.sPosToNodeId;
				//$("#helpBox").css("left", $("#" + sPosToNodeId).offset().left).css("top", $("#" + sPosToNodeId).offset().top);
			} else {
				$("#helpBoxWrapper").show();
				this.centerObjectToScreen(oLayer);
			}			
		},
		centerObjectToScreen : function(oLayer){
			// Center #helpBox
			var posX = Math.round( ($(window).width() - oLayer.width() ) / 2 );
			var posY = Math.round( ($(window).height() - oLayer.height() ) / 2 );
			posX = (posX < 0) ? 0 : posX;
			posY = (posY < 0) ? 0 : posY;
			
			//console.log("Soll: document.width: ",$(document).width(), "document.height: ",$(window).height(), "layerHeight: ", oLayer.height(), " | layerWidth: ", oLayer.width(), "posX: ", posX, " | posY: ", posY);
			//console.log("Vorher--> posX: ", oLayer.css("left"), "| posY: ", oLayer.css("top"));
			oLayer.css("left", posX).css("top", posY);
			//console.log("Danach--> posX: ", oLayer.css("left"), "| posY: ", oLayer.css("top"));
		},
		remove: function(){
			$("#helpBoxWrapper").remove();
			this.removeHandlers();
		}
	};
}
var goUtils = new Utilities();


/*********************   utilities for url handling ************************/

var goUrl = {
	loadURL : function(sURL){
		location.href = sURL;
		return false;
	},

	/*
	 * url
	 * params should be url encoded.
	 */
	createNewUrlWithAdditionalParams : function (url, params) {
		var hashpos = url.indexOf("#");
		var hashname = '';
		if (hashpos > 0) { 
			hashname = url.substring(hashpos); 
		  	url = url.substring (0, url.length-hashname.length);
		}
		if (url.indexOf('?') == -1) url = url +'?';
		return url + "&" + params + hashname;
		
	},

	/*
	 * setzt aktiv den hash in location bar, bewirkt das Scrollen des Browsers.
	 */
	go2Anchor : function (name){
		if (! name.startsWith("#")) { name = '#' + name;}
		if (name && name.length >1) { 
			if (isMinSafari3) { window.location.hash = ''; }/* Safaris need this */
			window.location.hash = name ;
		}
	}	

};

/*********************    Accordion Effect 1 **********************/
function accordionEffect() {
	$('.accordionSlider div').click (
		function () {
			var containerElement = $(this).next();
			var headerElement = $(this);
			if((containerElement.is('.accordionSlider .boxContent')) && (containerElement.is(':visible'))) {
				return false;
				}
			if((containerElement.is('.accordionSlider .boxContent')) && (!containerElement.is(':visible'))) {
				$('.accordionSlider .boxContent:visible').slideUp('slow');
				containerElement.slideDown('slow');   
				return false;
				}
		}
	);
}
$( function() { accordionEffect(); $('.accordionSlider').filter(":first").click();} );

/*********************    Accordion Effect 2 **********************/
/* This Effect does not automaticly close the next element */
function accordionEffect2() {
	$('.accordionOpener div').click (
		function () {
			if ($(this).next().is(":visible")) {
				$(this).next().slideUp();
				$(this).removeClass("open");
			} else {
				$(this).next().slideDown();
				$(this).addClass("open");
			}
		}
	);
}
$( function() { accordionEffect2(); $('.accordionOpener div').filter(":first").click();} );

/*********************    Accordion Effect 3 **********************/
/* This effect opens first the div element with the class "active" */
function accordionEffect3() {
	$('.accordionActive div').click (
		function () {
			var containerElement = $(this).next();
			var headerElement = $(this);
			if((containerElement.is('.accordionActive .boxContent')) && (containerElement.is(':visible'))) {
				return false;
				}
			if((containerElement.is('.accordionActive .boxContent')) && (!containerElement.is(':visible'))) {
				$('.accordionActive .boxContent:visible').slideUp('slow');
				containerElement.slideDown('slow');   
				return false;
				}
		}
	);
}
$( function() { accordionEffect3(); $('.accordionActive div').filter(".active").click();} );



/*********   for all close buttons within layerBox   ***************/
/* note: add class="clickClose" to a-node instead of inline onclick js-func-call.
 * The onready-call is only for the 1. load of the whole page.
 * For all ajax-requests, which replace the complete layerBox-Content,
 * add following code after <a href="#" class="clickClose"> - node
 *
 * <script type="text/javascript">closeButtonHandling();</script>
 *
 * because close-button is also reloaded, and so on-click-event.
 */
function closeButtonHandling (){
	$("a.clickClose").click(function(){
		var target = $(this).parents(".layerBox").attr("id");
		if (! isNull(target) && target.isNotEmpty()) {
			$("#"+target).css(goUtils.css.invisible);
		} 
		return false;
	});
};
$( function() { closeButtonHandling(); } );
	
/*********   Ansteuerung der Routenberechnung aus der Detailseite   ***************/
/*********   hierher ausgelagert aus HTML Code wegen Seitengröße    ***************/

function getRoute2Entry() {

  var routeForm = document.getRoute;
  var routeOptionAlwaysVisible = $('#routeOptionAlwaysVisible').val();

  if (routeOptionAlwaysVisible == 'DB') {

    var fromLOC = routeForm.routePos1A.value;
    var fromSTR = routeForm.routePos1B.value;
    
    var toLOC = routeForm.routePos2A.value;
    var toSTR = routeForm.routePos2B.value;
 
    var S = fromLOC + "," + fromSTR ;
    var A = toLOC + "," + toSTR ;

    var bahnForm = document.bahnReq;
    bahnForm.S.value = S;
    bahnForm.Z.value = A;
    bahnForm.submit();

  } else {
    GR.clearRoute();
    
    var waypoints = new Array(); 
    waypoints[0] = new WayPoint('to',arrCoordinates[0].lon,arrCoordinates[0].lat, null, 'off'); // no input
 	// Die Variable 'arrCoordinates' ist global und durch subscriberHomepageHeaderTemplate.xsl erzeugt worden.
 	
 	// Das Objekt 'GR' existiert nur, wenn JS für GoogleAPI geladen ist
 	// Die Aufruf Logik in mapTabTemplate.xsl sorgt dafür, dass diese Bedingung erfüllt ist.
	GR.calculate(waypoints, routeOptionAlwaysVisible);
	return false;
  }
}

/*********   Ansteuerung des Durckvorgangs aus der Detailseite      ***************/
/*********   hierher ausgelagert aus HTML Code wegen Seitengröße    ***************/

function orderPrint () {
	hideModalOverlay();
    goUtils.emitMessage('c'+ivwchid+'_det_print');
	goUtils.misTracking (misParameter4orderPrint); 
	// Die Variable 'misParameter4orderPrint' ist global und durch subscriberHomepageHeaderTemplate.xsl erzeugt worden.
	
	var url = document.URL;
	
	var pareas = getStrPrintAreas(); 
	if (pareas && pareas.length > 0) {
		url = goUrl.createNewUrlWithAdditionalParams(url, 'PAS='+encodeURIComponent(pareas));
	}
	
	goPrint.openPrintWindow('homepage', url); // force using this url
}

/*********   Hier wird bei Dealhamster angefragt ob es fuer eine bestimmte Branche ( Kategorie ) Gutscheine gibt ***************/

function getDealhamsterCoupons (dealhamsterSearchTerm){
    $.getJSON("/servlet/proxy?http://www.dealhamster.com/de/external/widget-simple?keyword=" + dealhamsterSearchTerm + "&affiliateId=300&page=1&format=json", null,
        function(data){
          if (data.coupons){
            $.each(data.coupons, function(i,item){
              $('<li><a href=/redirect.jsp?ACTION=el:dealhamster.box&amp;PAGE=dealhamsterBox&amp;URL=' + encodeURIComponent(item.link) + ' target=\"_blank\">' + item.title + '</a></li>').prependTo("#coupon");
              if ( i == 3 ) return false;
            });
          
	  }	
          if ($("#contextNav_dealhamster").is(":hidden")) {
			$("#contextNav_dealhamster").show("slow");
		  } else {
			("#contextNav_dealhamster").slideDown();
		  }
          
        });
	return false;
}



/*********   Hier wird nachgefragt ob es für die aktuelle IP einen Standort gibt ***************/

function getIPLocation (){
    $.getJSON("IDA2?ACTION=resolveIP&PAGE=ipTargeting&MIME=json", null,
        function(data){
          if (data.IPTargeting.Location){
          	alert(data.IPTargeting.Location);	          
	  }	
          
        });
	return false;
}