/*
* casco: a framework for rapid database driven application development written in PHP
* Copyright 2006, 2007 Lex Vogelaar, Vogelaar ICT&MultiMedia
* Copyright 2006, 2007 Stefan van de Rijt, TrackByte, www.trackbyte.nl
* 
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License, version 2.1, as published by the Free Software Foundation;
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*
* snail mail:
* Vogelaar ICT&MultiMedia
* Roggehegge 3
* NL-6225 JM Maastricht
* The Netherlands
*
* email:
* casco@vogelaar.cc
*/

var infowindow;

function getWindowWidth()
{
	if (window.self && self.innerWidth) {return self.innerWidth;}
	if (document.documentElement && document.documentElement.clientWidth) {return document.documentElement.clientWidth;}return 0;
}

function getWindowHeight()
{
	if (window.self && self.innerHeight) {return self.innerHeight;}
	if (document.documentElement && document.documentElement.clientHeight) {return document.documentElement.clientHeight;}return 0;
}

function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return [ scrOfX, scrOfY ];
}

function getScrollWidth()
{
	scrollb = getScrollXY();
    return scrollb[0];
}

function getScrollHeight()
{
	scrollb = getScrollXY();
	return scrollb[1];   
}

function getElementPos(el, final_parent)
{
	return [getLeft(el, final_parent), getTop(el, final_parent)];
}

function getLeft(el, final_parent){
	element = document.getElementById(el);
  left=0;
  while (element && element.id != final_parent.id) {
	 left += element.offsetLeft;
	 element = element.offsetParent;
  }
  return left;
}

function getTop(el, final_parent) {
	element = document.getElementById(el);	
  atop=0;
  while (element && element.id != final_parent.id) {
	 atop += element.offsetTop;
	 element = element.offsetParent;
  }
  return atop;
}

function closeInfoWindow()
{
	infowindow.close();	
}

function window_popup(href, width, height)
{
	effectduration = 0.25;
	effectshow = Effect.Appear;
	
		// screen already exists, so destroy it before making a new one
	if($('info_popup_div'))
	{
		infowindow.destroy();
		effectduration = 0;
		effectshow = Effect.Appear;
	}
	  

	infowindow = new casco_PopupWindow('info_popup_div', {width: width, height: height, url: href, effectShow: effectshow, duration: effectduration, durationHide: 0, isModal: true});

	return false;
}

function window_div(windowName, elementID, width, height, title)
{
	handle = new casco_PopupWindow(windowName, {content: $(elementID).innerHTML , width: $(elementID).offsetWidth, height: $(elementID).offsetHeight, isModal: true, duration: 0, durationHide: 0, title: title});
	$(elementID).style.visibility = 'hidden';
	
	popup_form = getChildElementById(elementID, handle.win.getId(), 'form');
	if(popup_form) 
	{
		setTimeout("Form.focusFirstElement(popup_form)", 100);	
	}
	
	return false;
}



function text_limit(textarea, info, max_length, has_counter)
{
	field = $(textarea);
	countfield = $(info);

	if (field.value.length > max_length)
	{
		field.value = field.value.substring(0, max_length);
	}
	else
	{
		if(has_counter) 
		{
			countfield.innerHTML = (max_length - field.value.length);
		}
	}
}	

/*
* casco slideshow
* Stefan van de Rijt
*/

var casco_slideshow = Class.create();
casco_slideshow.prototype =
{
	initialize: function(id, target)
	{
		this.id 			= id;
		this.target			= target;
		this.options = Object.extend(
		{
			show:	3000,
			fade: 		3
		}, arguments[1] || {});
		this.slideShowSpeed		= this.options.show;
		this.crossFadeDuration	= this.options.target;

		this.pictureArray = new Array();
		
		this.preLoad;
		this.tss;
		this.iss;
		this.jss = 0;
		this.pss;
	},
	
	addItem: function(filename, text, url)
	{
		this.pictureArray[this.pictureArray.length] = new Array(filename, text, url);
	},
	
	loadShow: function()
	{
		this.pss = this.pictureArray.length-1;
		this.jss = 0;
	
		this.preLoad = new Array();
		for (this.iss = 0; this.iss < this.pss+1; this.iss++)
		{
			this.preLoad[this.iss] = new Image();
			this.preLoad[this.iss].src = this.pictureArray[this.iss][0];
			this.preLoad[this.iss].alt = this.pictureArray[this.iss][1];
			this.preLoad
		}
		clearTimeout(this.tss);
		this.runSlideShow();		
	},
	
	runSlideShow: function()
	{

	
		if (document.all)
		{
			target = this.target;
			eval("imglink = document.images."+target+";");
			imglink.style.filter="blendTrans(duration="+this.options.fade+")";
			imglink.style.filter="blendTrans(duration=CrossFadeDuration)";
			imglink.filters.blendTrans.Apply();
		}

		$(this.target).src = this.preLoad[this.jss].src;
//		$(this.target).innerHTML = Text[jss];		

		if (document.all) imglink.filters.blendTrans.Play();
		this.jss++;
		if (this.jss > (this.pss)) this.jss=0;
		me = this;
		this.tss = setTimeout('me.runSlideShow()', this.options.show);
  }
};



/*
* Casco infoDiv
* Customized tooltip window
* may 17 2007 - Stefan van de Rijt
*/
document.write('<div id="infoDiv" style="display:none; z-index:999">&nbsp;</div>');

function setInfoDiv(html, target)
{
	if(target != null)
	{
		$(target).innerHTML = html;
	}
	else
	{
		$('infoDiv').innerHTML = html;
		$('infoDiv').style.zindex = '99';		
		$('infoDiv').style.position = 'absolute';
		$('infoDiv').style.top =  '70px';
		$('infoDiv').style.right = '50px';		
		$('infoDiv').style.display = '';		
	}
		
}

function hideInfoDiv()
{
		document.getElementById('infoDiv').style.display = 'none';
}

/*
* Casco pageProcessing
* march 14 2007 - Stefan van de Rijt
*/
var dialogCounter = 0;

function showProcessing(html)
{
	dialogCounter++;
	if(dialogCounter == 1)
	{
		Dialog.info(html,
			{ width: 250, height: 100, showProgress: true, hideEffect:Element.hide, showEffect:Element.show, className: "casco"}
		);
	}
}

function hideProcessing()
{
	Dialog.closeInfo();
	dialogCounter = 0;
}

/*
* Casco Errorhandler plugins
* january 19 2007 - Stefan van de Rijt
*/

/**
 * This javascript object will listen to the onChange event of an input element and will trigger a validation function. 
 * This function can include the show() function to show an validation error in the linked div element.
 * 
 * @param elementID		The ID of the input element
 * @return				void
 * @see					prototype.js
 * @see					scriptacolous
 * @since				cascojs 1.0
 * @author				Stefan van de Rijt
 */
var casco_ErrorHandler = Class.create();
casco_ErrorHandler.prototype =
{
	// void Constructor(string id)
	// parameters:	string error_message, string classname_plugin_normal, string classname_plugin_error, string classname_error,
	// bool show_error, function validation, bool required
	
	initialize: function(id)
	{
		this.id 			= id;
		this.hasError		= false;
		this.inits			= true;
		this.options = Object.extend(
		{
			error_message:			 "",
			classname_plugin_normal: "plugin_standard",
			classname_plugin_error:	 "plugin_standard_error",			
			classname_error:  		 "plugin_errorfield",
			errorfield:				 "msg_" + this.id,
			show_error:				 false,
			validation:				 false,
			required:				 false
		}, arguments[1] || {});
		this.errorfield					= this.options.errorfield;
		this.error_message				= this.options.error_message;
		this.show_error 				= this.options.show_error;
		$(this.id).className			= this.options.classname_plugin_normal;
		$(this.errorfield).className 	= this.options.classname_error;
		
		var me = this;
		this.observer = new Form.Element.EventObserver(this.id, function() { me.validate(); });
	},
	
    /**
	 * This function is normally triggered by the event listner of the input element. You can call this function for example 
	 * when you want to validate the input element manually.
     * If there is a validation function configured, this function will be called!
     */	
	validate: function()
	{
		if(this.options.required && $(this.id).value.length == 0)
		{
			this.error_message = "This is a required field";
			this.show();
		}
		else
		{
					
			if(!this.options.validation)
			{
				this.hide();
			}
			else
			{
				this.options.validation();
			}
		}
	},
	
    /**
	 * This function will show the error message.
     */		
	show: function()
	{
			$(this.id).className 			= this.options.classname_plugin_error;		
			$(this.errorfield).innerHTML	= this.error_message;
	
			// errorfield is already visible
			if(!this.hasError)
			{
				$(this.errorfield).style.display = "none";
				this.hasError = true;
				new Effect.Appear(this.errorfield);
				new Effect.BlindDown(this.errorfield, {duration:.3});		
			}
	},
	
    /**
	 * This function will hide the error message.
     */			
	hide: function()
	{
		$(this.id).className = this.options.classname_plugin_normal;
		
		if(this.hasError)
		{
			new Effect.Appear(this.errorfield);
			new Effect.BlindUp(this.errorfield, {duration:.3});
			$(this.errorfield).innerHTML = "&nbsp;";
			this.hasError = false;
		}				
	},
	
    /**
	 * This function will set a new value into the input thing.
     */			
	setValue: function(newValue)
	{
		$(this.id).value = newValue;
	},	
	
    /**
	 * This function will set the error message.
	 *
	 * @param new_message	the string that will apear in the error message when the show function is called
     */			
	setMessage: function(new_message)
	{
		this.error_message = new_message;
	}
};	


/*
* Casco Popup window
* Janary 05 2007 - Stefan van de Rijt
 */

var casco_PopupWindow = Class.create();
casco_PopupWindow.prototype = 
{
  // Constructor
  initialize: function(id) 
  {

	this.id = id;
    this.options = Object.extend(
	{
	  height:   	400,
	  width:    	400,
	  minHeight:	20,
	  minWidth:		100,
	  maxHeight:	false,
	  maxWidth:		false,
	  top:      	0,
	  left:     	0,
	  title:    	"&nbsp;",
	  url:      	"",
	  resizable:	true,
	  minimizable:	true,
	  maximizable:	true,
	  draggable: 	true,
	  duration: 	0,
	  durationHide: 0,
	  effectShow: 	Element.show,
	  effectHide: 	Element.hide,
	  isModal: 		false,
	  center:		true,
	  content:		false,				
	  autosize:		true,
	  closefunction: false,
	  skin:			"casco"
    }, arguments[1] || {});

		// popupwindow already exists, destroy it first
	this.win = new Window(id, 
	{
		className: 			this.options.skin, 
		title: 				this.options.title, 
		width: 				this.options.width, 
		height:				this.options.height, 
		maxHeight:			this.options.maxHeight,
		maxWidth:			this.options.maxWidth,
		minHeight:			this.options.minHeight,
		minWidth:			this.options.minWidth,		
		top: 				this.options.left,
		left: 				this.options.left, 
		resizable: 			this.options.resizable, 
	  	minimizable:		this.options.minimizable,
	  	maximizable:		this.options.maximizable,		
		url: 				this.options.url, 
		showEffect: 		this.options.effectShow,
		hideEffect: 		this.options.effectHide,		
		showEffectOptions:	{duration: this.options.duration},
		hideEffectOptions:	{duration: this.options.durationHide}
	}) 
	
	if(this.options.autosize)
	{
		windowAff = this.win;
		resizeObserver = 
		{
			onEndResize: function(eventName, win)
			{
				windowAff.updateWidth();
				windowAff.updateHeight();
			}
		}
		Windows.addObserver(resizeObserver);
	}
	
	if(this.options.closefunction)
	{
		windowAff = this.win;
		Windows.addObserver(this.options.closefunction);
	}	

	if(this.options.content)
	{
		this.setContent(this.options.content);
	}
	this.win.toFront();
	this.win.setDestroyOnClose();
	
  	if(this.options.center)
	{
		if(this.options.left > 0 || this.options.top > 0)
		{
			this.win.showCenter(this.options.isModal, this.options.left, this.options.top);			
		}
		else
		{
			this.win.showCenter(this.options.isModal);
		}
		WindowCloseKey.init();
	}
	
	else
	{
		
		this.win.show();
		WindowCloseKey.init();
	}	
  },
  
  resetWindow: function()
  {
	this.win.updateHeight();
	this.win.updateWidth();  	
  },

  destroy: function()
  {
	  this.win.destroy();
  },
  
  close: function()
  {
	  $(this.id+'_close').onclick();
  },
  
  setContent: function(html)
  {
		this.win.getContent().innerHTML = html;
  },
  
  setSize: function(width, height)
  {
	  this.win.setSize(width, height);
  },
  
  updateHeight: function()
  {
		this.win.updateHeight();  
		var hhhh = $H(this.win.getSize());
		alert(hhhh.toQueryString());
  },
  
  updateWidth: function()
  {
		this.win.updateWidth();	  
  },
  
  centerWindow: function()
  {
	  this.win.showCenter();
  }
};




var ajaxInProgress = false;

function getBrowser()
{
	var version = navigator.appVersion;
	var version_array = version.split("; ");
	return version_array[1];
}

var stopts = false;
var tel = 0;

function submitFormAfterValidate(form_id, html_process)
{
/*	showProcessing(html_process);
	if(ajaxInProgress)
	{
		setTimeout("submitFormAfterValidate('"+form_id+"',html_process)", 100);
	}
	else
	{*/
		document.getElementById(form_id).submit();
	/*}*/
}

function resetErrorBox(el)
{
	document.getElementById(el).innerHTML = "&nbsp;";
}
 
function getChildElementById(id, parent, tagName)
{
	var divs = document.getElementsByTagName(tagName);
	for(i=0; i<divs.length; i++)
	{
		if(hasParent(divs[i], parent)) 
		{
				return divs[i];
		}
	}		
	return false;
}

function hasParent(element, parent)
{
	if(!element.parentNode) return false;
	else
	{
		if(element.parentNode.id == parent)	return true;
		else return hasParent(element.parentNode, parent);
	}
}

/**
 * Script by Michel Bohn
 */
Position.Window = {
	//extended prototypes position to return
	//the scrolled window deltas
	getDeltas: function() {
		var deltaX =  window.pageXOffset
			|| document.documentElement.scrollLeft
			|| document.body.scrollLeft
			|| 0;
		var deltaY =  window.pageYOffset
			|| document.documentElement.scrollTop
			|| document.body.scrollTop
			|| 0;
		return [deltaX, deltaY];
	},
	//extended prototypes position to
	//return working window's size, 
	//copied this code from the 
	size: function() {
		var winWidth, winHeight, d=document;
		if (typeof window.innerWidth!='undefined') {
			winWidth = window.innerWidth;
			winHeight = window.innerHeight;
		} else {
			if (d.documentElement && typeof d.documentElement.clientWidth!='undefined' && d.documentElement.clientWidth!=0) {
				winWidth = d.documentElement.clientWidth
				winHeight = d.documentElement.clientHeight
			} else {
				if (d.body && typeof d.body.clientWidth!='undefined') {
					winWidth = d.body.clientWidth
					winHeight = d.body.clientHeight
				}
			}
		}
		return [winWidth, winHeight];
	}
}

//my own custom effect that basically
//calls the Effect.Move Scriptaculous
//effect with the correct window offsets
Effect.KeepFixed = function(element, offsetx, offsety) {
	var _scroll = Position.Window.getDeltas();
	var _window = Position.Window.size();
	var elementDimensions = Element.getDimensions(element);
	var eWidth = elementDimensions.width;
	var eHeight = elementDimensions.height;
	var moveX = _window[0] - eWidth + _scroll[0] + offsetx;
	var moveY = _window[1] - eHeight + _scroll[1] + offsety;
	return new Effect.Move(element, { x: moveX, y: moveY, mode: 'absolute' });
}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }
}	
