/*  general javaScript enhancements   ---------------------*/

// extend default Array object: see if a needle exists in an array
// let op: gebruik $.inArray dus de jQuery inArray function!
if (!Array.prototype.inArray) {
   Array.prototype.inArray = function(needle) {
      for (var i=0; i < this.length; i++) {
         if (this[i] === needle ) 
            return true;
      };
      return false; 
   };
};

// push a value on the stack only if it doesn't exist already in the array:
if (!Array.prototype.pushUnique) {
   Array.prototype.pushUnique = function(val){
      if (!this.inArray(val)) {
         this.push(val);
      };
   };
};

// replace < and > with html entities &lt; and &gt;
if (!String.prototype.htmlEncode) {
   String.prototype.htmlEncode = function(){
      var data = this.replace(/\</g, "&lt;");
      return data.replace(/\>/g, "&gt;");
   };
};
// restore htmlentities back to < and >
if (!String.prototype.htmlDecode) {
   String.prototype.htmlDecode = function(){
      var data = this.replace(/\&lt;/g, "<");
      return data.replace(/\&gt;/g, ">");
   };
};

// replace placeholder %s in a string with the given parameters (compare php sprintf())
// vb gebruik: msgEmptyFields = texts.requiredFields.insertParam('vijf') waarbij 
// texts.requiredFields is: "Vul aub de volgende %s verplichte velden in"
if (!String.prototype.insertParam) {
	String.prototype.insertParam = function() {
		var params = arguments;
		var parts = this.split('%s');
		var res = '';
		for (var i=0; i < params.length; i++) {
			res += parts[i] + params[i];
		}
		if (typeof parts[i] !== 'undefined') {
			res += parts[i];
		}
		return res; 
	};
};

var va = va || {} // vaita namespace

/**
* Returns the week number for this date. dowOffset is the day of week the week
* "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday),
* the week returned is the ISO 8601 week number.
* @param int dowOffset
* @return int
* origneel breidt deze functie het default Date obj uit: 	Date.prototype.getWeek
* echter niet doen want dit leidt tot een invalid _prototype_ voor ieder Date obj waardoor geen ajax POSTs meer plaatsvinden! 
*/
va.getWeek = function(jsDate) {

	dowOffset = 1; //default dowOffset to 1 = monday
	var newYear = new Date(jsDate.getFullYear(),0,1);
	var day = newYear.getDay() - dowOffset; //the day of week the year begins on
	day = (day >= 0 ? day : day + 7);
	var daynum = Math.floor((jsDate.getTime() - newYear.getTime() - (jsDate.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
	var weeknum;
	//if the year starts before the middle of a week
	if(day < 4) {
		weeknum = Math.floor((daynum+day-1)/7) + 1;
		if(weeknum > 52) {
			nYear = new Date(jsDate.getFullYear() + 1,0,1);
			nday = nYear.getDay() - dowOffset;
			nday = nday >= 0 ? nday : nday + 7;
			/*if the next year starts before the middle of
			the week, it is week #1 of that year*/
			weeknum = nday < 4 ? 1 : 53;
		}
	} else {
		weeknum = Math.floor((daynum+day-1)/7);
	}
	return weeknum;
};

//if (!Date.prototype.getWeek) {
//	Date.prototype.getWeek = function (dowOffset) {
//	/*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com */
//	
//		dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 1; //default dowOffset to 1
//		var newYear = new Date(this.getFullYear(),0,1);
//		var day = newYear.getDay() - dowOffset; //the day of week the year begins on
//		day = (day >= 0 ? day : day + 7);
//		var daynum = Math.floor((this.getTime() - newYear.getTime() - (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
//		var weeknum;
//		//if the year starts before the middle of a week
//		if(day < 4) {
//			weeknum = Math.floor((daynum+day-1)/7) + 1;
//			if(weeknum > 52) {
//				nYear = new Date(this.getFullYear() + 1,0,1);
//				nday = nYear.getDay() - dowOffset;
//				nday = nday >= 0 ? nday : nday + 7;
//				/*if the next year starts before the middle of
//				the week, it is week #1 of that year*/
//				weeknum = nday < 4 ? 1 : 53;
//			}
//		} else {
//			weeknum = Math.floor((daynum+day-1)/7);
//		}
//		return weeknum;
//	};
//}; 


//create 'loading' span with gif.  Needs JQuery
va.createLoadingIndicator = function(txt, pathTovaLib) {
	var ltxt = txt || '';
	var path = va.pathToLib || pathTovaLib || '';
	var $loading = $('<span id="vaLoading">' + ltxt +  '</span>')
							.css({
								'font-weight': 'bold', 
								'vertical-align': 'top'
							});
	var $img = $('<img src="' + path + 'vaLib/images/loading.gif" />')
							.css({
									'width': '28px', 
									'height': '28px', 
									'margin-left': '2em'
								}); 
	return $loading.append($img);
}

// get the document in the iframe:
va.getDocumentFromFrame = function(fid) {
   if (fid.contentDocument) {
		return fid.contentDocument;
	} else {
		if (fid.contentWindow) {
			return fid.contentWindow.document;
		} else {
			return window.frames[fid].document;
		};
	};
};

/** 
 * fill out the remaining space with non=breakable spaces
 * @param {Object} str				string to append with spaces
 * @param {Object} totalWidth		total width of string + spaces
 */
va.addSpaces = function(str, totalWidth) {
	for (var i = totalWidth - str.length; i >= 1; i--){
		str += "&nbsp;";
	};
	return str;
};

va.fillWithChar = function(str, filler, totalWidth) {
	for (var i = totalWidth - str.length; i >= 1; i--){
		str += filler;
	};
	return str;
};

/** convert an array with objects to an object with objects. Usefull for posting to PHP because the ajax post only allows 
 * string and map data to be posted.
 * @param arr			array with objects
 * @objName				string. First object will be visible in the PHP post data as $_POST['test0'] when objName = 'test'
 * 						Second is $_POST['test1'] etc.
 * example of input arr: {naam: "a", value: 1, noiets: "ok"}, {naam: "b", value: 2, noiets: "ok"}, {naam: "c", value: 3, noiets: "ok"}];
 * @usage:
 * myMappie = va.getMapFromArray(test, 'tessie');
 *	$.post('test.php', myMappie);		
 */
va.getMapFromArray = function(arr, objName){
	var myMap = {};
	$.each(arr, function(i, val){
		myMap[objName+i] = val; 
	});
	return myMap;
};

/** serialize array with objects to a php parseble string
 *  returned string with 3 objs looks like: naam=a;value=1;noiets=ok;|naam=b;value=2;noiets=ok;|naam=c;value=3;noiets=ok;
 */ 
va.serializeArrayWithObjs = function(arr){
	var str = '';
	for (var j=0; j< arr.length; j++) {
		for (var i in arr[j]) {
			 str+= i + "=" + arr[j][i] + ";";
		};
		if (j < arr.length-1) str +="|";
	};
	return str;
};

/** show a Yes/No modal dialog
 * @param {string} msg					message to show to the user
 * @param {function} callbackIfYes		when the user clicks the Yes button this function is called
 */
va.showMessageYesNo = function(msg, callbackIfYes, callBackIfNo) {

	// add <div> to body:
	var msgID = "dialogMsg" + new Date().getTime();				// add timestamp to make the id unique in case more popups are shown.
	$popupMsg = $('<div id="' + msgID + '"><p>' + msg + ' </p></div>').prependTo($('body'));
	var isYesBtnClicked = false;
	
	var btnYesClicked = function(){ 
		isYesBtnClicked = true;
		$popupMsg.dialog('close');		// will trigger close event which will call closeDialog()
		callbackIfYes();
	};
	var btnNoClicked = function(){ 
		$popupMsg.dialog('close'); 
	};
	var closeDialog = function(){ 
		$popupMsg.dialog('destroy');
		$popupMsg.remove()					// completely remove the DIV
		// if the dialog is closed with the X in the upper right corner also call the btnNo clicked function
		if (isYesBtnClicked === false && typeof callBackIfNo !== 'undefined') {
			callBackIfNo();
		}; 
	};
	// calculate dialog Width:
	var dlgWidth = msg.length * 7 + 20;			//in pixels
	if (dlgWidth + 100 > document.width) {
		dlgWidth = document.width - 200;
	}
	//create dialog:
	var dlgParams = {
		buttons: {
			'Ja': btnYesClicked,
			'Nee': btnNoClicked
		},
		close: closeDialog,
      resizable: false,
      width:  dlgWidth,
      modal: true,
		autoOpen: false,
      title: 'Maak aub een keuze',
      overlay: {
         backgroundColor: '#000',
         opacity: 0.6
      }
	};
	$popupMsg.dialog(dlgParams).dialog('open');
}

/** show a message in a modal dialog. NOTE: only ONE dialog can be shown.
 * @param {string}	msg					message to show to the user
 * #param {string} 	msgTitle				message title
 * @param {function} funcContinue		Optional. When the user clicks the Ok button this function is called
 */
va.showMessage = function(msg, msgTitle, funcContinue) {

	var closeMe = function() {
		$popupMsg.dialog('close');		// will trigger close event which will call closeDialog()
	}
	var closeDialog = function(){ 
		$popupMsg.dialog('destroy');
		$popupMsg.remove()					// completely remove the DIV
		if (typeof funcContinue !== "undefined") {
			funcContinue();
		}
	};

	// first close another dialog if there's one open
	$popupMsg = $('#vaMsgDialog'); 
	if ($popupMsg.length > 0) {
		closeMe();
	}
	$popupMsg = $('<div id="vaMsgDialog"><p>' + msg + ' </p></div>').prependTo($('body'));
		
	// calculate dialog Width:
	var dlgWidth
	if ( (msg.length * 7 + 20) < 500 ){
		dlgWidth = msg.length * 7 + 20;
	} else {
		dlgWidth = 400;	
	} ;			//in pixels
	
	//create dialog:  don't set the height, it's default option is 'auto' so it resizes automatically
	var dlgParams = {
		buttons: {
			'Ok': closeMe
		},
      resizable: false,
      width: dlgWidth, 
      modal: true,
		autoOpen: false,
		close: closeDialog,
      overlay: {
         backgroundColor: '#000',
         opacity: 0.6
      }
	};
	if (typeof msgTitle !== 'undefined') {
		dlgParams.title = msgTitle;
	}
	$popupMsg.dialog(dlgParams).dialog('open');
};

/**
 * test the result from an $.post
 * @param {mixed} data					data returned from the ajax post
 * @param {bool} showError				if true the error will be shown in a messagebox (va.showMessage)
 * @param {string} logErrorContext	optional. Error context. If set the error will be posted to vaLib/logAjaxError.php for logging.
 */
va.testPostResult = function(data, showError, logErrorContext) {
	
	var arrRet = [false, ''];
	if (typeof data === 'undefined' || data === null) {
		arrRet[1] = "De post retourneert GEEN data!";
	} else if (typeof data.result === 'undefined') {
		if (typeof data === "object") {
			var props = '';
			for (var p in data) {
				props += p + ", ";
			};
			arrRet[1] = "Object met onjuiste properties geretourneerd. properties: <br /> " + props;
		} else {
			arrRet[1] = "Onjuiste data geretourneerd. Data: <br /> " + data;
		}	
	} else if (data.result) {
		arrRet[0] = true;
	} else {
		arrRet[1] = "Deze database actie is mislukt. " + (typeof data.message !== 'undefined'? data.message: '');
	};
	if (arrRet[0] === false) {
		if (typeof showError !== "undefined" && showError) {
			va.showMessage(arrRet[1], "Onjuiste response van de database");
		};
		if (typeof logErrorContext !== "undefined" && logErrorContext) {
			var logToFile = (typeof va.pathToLib !== 'undefined'? va.pathToLib: '') + 'vaLib/logAjaxError.php';
			$.post(logToFile, {ajaxErrMessage: logErrorContext + ": " + arrRet[1]});   //log the error to the backend:
		};
	}
	return arrRet;
};

va.addPostOkDiv = function($appendToDiv) {
	$('<div></div>').addClass('resultMessage resultSuccess')
		.empty().html('De wijzigingen zijn succesvol opgeslagen.')
		.appendTo($appendToDiv).show();
};

// va.manageSelectOptions is defined in vaLib/js/manageSelectOptions.js

va.displayAsCurrency = function(n) {
	var t = n.toFixed(2);
	t = t.toString();
	return t.replace(/\./, ",");		// replace dot with comma
};

/** jQuery plugin to apply alternate row colors in a tabel by adding class 'odd' or class 'even'
 * 
 */
jQuery.fn.alternateRowColors = function(){
	// row striping:
	$('tbody tr:odd', this).removeClass('even').addClass('odd');		// this refers to the table
	$('tbody tr:even', this).removeClass('odd').addClass('even');
	return this; 				// make this plugin method chainable by returning this							
};

$(document).ready(function() {
   
   /* creeer leesmeer... toggle teksten. noodzakelijke HTML source:
          <span class="leesmeer-toggle">lees meer...<br /></span>
         <span class="leesmeer-text">De document root bla bla </span>
         Zorg voor styling in aparte css file. Voorbeeld:
         .leesmeer-text{   
            display: none;
            padding: 0.4em;
            border: 1px solid silver;
            background-color: #FFFFBF;
            display: inline-block;
            margin-top: 0.4em;
            margin-bottom: 0.4em;
         }
         .leesmeer-toggle { 
            background-color: #eeeeee;
            cursor: pointer;
            text-decoration: underline;
            display: inline-block;
         }         
   */
   var leesmeerToggleTxt;
   $('.leesmeer-text')
      .hide()         // eerst alle leesmeer teksten verbergen
      .click(function(){
         $(this).prev('.leesmeer-toggle').text(leesmeerToggleTxt);
         $(this).hide();
      });

   $('.leesmeer-toggle').toggle(
      function(){
         leesmeerToggleTxt = $(this).text();
         $(this).text('hide...');
         $(this).next('.leesmeer-text').show();
      },
      function(){
         $(this).text(leesmeerToggleTxt);
         $(this).next('.leesmeer-text').hide();
      }
   )
   //-- einde leesmeer toggle teksten
});

