//-----------------------------------------------------------------//
// www.decode.uk.com library file
//
//
//
//
//
//-----------------------------------------------------------------//

//INDEX
//function createTarget(form)
//function ajax()
//function Resizeable(elementId,handle,opts)
//function calendar(name, container, height, width, month, year)



//function to allow formatting of _blank new window that form is sent to
// place this as the onSubmit of the form and place normal new window parameters after a colon in the target
// property of the form tag. eg  
//	<form action="YOUR-CGI-SCRIPT.CGI" method=get
//		target="foobar:width={window.screen.width/2},
//      	  height={myHeight},
//        	  scrollbars,
//       	  {(isResizable)?'resizable':''},
//       	  status"
//		onSubmit="return createTarget(this);">
// see http://javascript.internet.com/forms/form-target-formatting.html for more details.
// Original:  Cyanide_7 (leo7278@hotmail.com) 
// Web Site:  http://www7.ewebcity.com/cyanide7 
function createTarget(form) {
_target = form.target;
_colon = _target.indexOf(":");

if(_colon != -1) {
	form.target = _target.substring(0,_colon);
	form.args = _target.substring(_colon+1);
} else if(typeof(form.args)=="undefined") {
	form.args = "";
}

if(form.args.indexOf("{")!=-1) {
	_args = form.args.split("{");
	form.args = _args[0];
	for(var i = 1; i < _args.length;i++) {
		_args[i] = _args[i].split("}");
		form.args += eval(_args[i][0]) + _args[i][1];
    }
}

form.args = form.args.replace(/ /g,"");
_win = window.open('',form.target,form.args);

if(typeof(focus)=="function")
	_win.focus();
	
return true;
}





//Modified by Tom Elmore from example by Aleem Bawany 
//url: http://aleembawany.com/weblog/webdev/000051_ajax_instant_tutorial.html
//instatiate object. object.loadUrl can then be used.
//pass dest(ination) of back end, id of the container where the result will be displayed, the method (post or get)
// and any var(iable)s that need to be passed in the form "a=1&b=2&name=tromm" etc
function ajax(){
var recipient = String;
var callBack = Object;
	this.loadUrl = function(dest,container,method,vars,callBackFunction){
		
		if(callBackFunction) callBack = callBackFunction;
		else callBack = null;
		
		try {
		xmlhttp = window.XMLHttpRequest?new XMLHttpRequest():
			new ActiveXObject("Microsoft.XMLHTTP");
		} 
		catch (e) {
			alert('Your browser does not support ajax');
		}
		
	recipient = container;
		
	xmlhttp.onreadystatechange = this.trigger;
	switch(method.toLowerCase()){
		case 'get':
			xmlhttp.open("GET", dest+'?'+vars);
			xmlhttp.send(null);
		break
		case 'post':
			xmlhttp.open("POST", dest);
			xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
			xmlhttp.send(vars);
		break
		default: alert('invalid method when requesting from '+dest);
	}
	}	
	
	this.trigger = function(){
		if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) {
			HTML = xmlhttp.responseText;
			document.getElementById(recipient).innerHTML = HTML;

			if(callBack) callBack();
		} 
	}
}







//Class to create a resizeable div area. ElementId is the id of the scalable area, handle is a second div  
//area which can be styled or left blank to provide a handle for resizing the element.
//opts is an optional object with the properties constraints and change. Constraints can be vertical or 
//horizontal to restrict resizing to one axis. Change is the handle of a callback function run while area is
//being resized.
//Example:- this html:
//			<div id='left' style='position:relative; left:100x; top:100px; background-color:#FFFFCC; width:100px; height:100px; left:100px; top:100px;'>
// 				<div id='titleBar' style='color:#FFFFFF; background-color:#3366CC; height:20px; width:100%;'>Draggable Box</div>
//				<div id='content' style='overflow:scroll; height:100%;'>
//				</div>
//				<div id='handleArea' style=' width:15px; height:15px; top:105px; background-image:url(http://www.ideamaker.net/lib/media/resize.gif);'></div>
//			</div>
//in conjuction with this script:
//		 new Resizeable('left','handleArea');
//		 new Draggable('left',{handle:'titleBar'});
//creates a window like box
//Requires prototype.js and scriptaculous
//Oct 2006 Tom Elmore 
function Resizeable(elementId,handle,opts){
	//element to be resized and handle that will used to drag it to desired size
	this.elementId = elementId;
	this.handle = handle;

	//make sure handle is accessible unless deliberately hidden
	if(!document.getElementById(handle).style.zindex) document.getElementById(elementId).style.zindex = 999;
	
	//adjust for unspecified position
	if(!document.getElementById(handle).style.position){ 
		document.getElementById(handle).style.position = 'absolute';
		if(!document.getElementById(handle).style.left){
			defaultLeft = ( parseInt(document.getElementById(elementId).style.width) - parseInt(document.getElementById(handle).style.width) );
			document.getElementById(handle).style.left = defaultLeft + 'px';
		}
		if(!document.getElementById(handle).style.top){
			defaultTop = ( parseInt(document.getElementById(elementId).style.height) - parseInt(document.getElementById(handle).style.height) );
			document.getElementById(handle).style.top = defaultTop + 'px';
		}
	}
	
	//handle's position must be absolute so as not to interfere with the element's content
	document.getElementById(handle).style.position = 'absolute';
	
	//record relative position of handle within area to maintain position when dragged	
	this.handleOffsetX = parseInt(document.getElementById(elementId).style.width) - parseInt(document.getElementById(handle).style.left);
	this.handleOffsetY = parseInt(document.getElementById(elementId).style.height) - parseInt(document.getElementById(handle).style.top);
	
	//optional arguments
	if(opts && opts.constraint) this.constraint = opts.constraint;
	if(opts && opts.change) this.change = opts.change;
	
	// make handle draggable
	createDraggable = 'new Draggable("' + handle + '",{';
	if(opts && opts.constraint) createDraggable += 'constraint:"' + opts.constraint + '", ';
	createDraggable += 'change:this.resizeElement.bind(this)});'; //must bind else this keyword will refer to Draggable in resizeElement rather than Resizeable
	eval(createDraggable);
}
Resizeable.prototype.resizeElement = function(){
	if(this.constraint != 'vertical'){
		newWidth = parseInt(document.getElementById(this.handle).style.left) + this.handleOffsetX ;
		document.getElementById(this.elementId).style.width = newWidth + 'px';
		
		//restrict handle from going past min dimension
		if(parseInt(document.getElementById(this.handle).style.left) < 0) document.getElementById(this.handle).style.left = '0px';
		minWidth = this.handleOffsetX;
		if(parseInt(document.getElementById(this.elementId).style.width) < minWidth) document.getElementById(this.elementId).style.width = minWidth + 'px';
	}
	if(this.constraint != 'horizontal'){
		newHeight = parseInt(document.getElementById(this.handle).style.top) + this.handleOffsetY;
		document.getElementById(this.elementId).style.height = newHeight + 'px';
		
		//restrict handle from going past min dimension
		if(parseInt(document.getElementById(this.handle).style.top) < 0) document.getElementById(this.handle).style.top = '0px';
		minWidth = this.handleOffsetY;
		if(parseInt(document.getElementById(this.elementId).style.height) < minWidth) document.getElementById(this.elementId).style.height = minWidth + 'px';
	}
	
	//if specified run callback
	if(this.change) this.change();
}







// Class of calendar which creates a selectable calendar of the size requested within an existing div area
// container. The handle of the instance created must be passed to the creator as 'name'. Month and year are
//optional and set the default date of the calendar.
//
//properties: 	month - numeric representation of the month being viewed
//				year - four digit representation of the year
//				monthName - full writen month name
//				selectMulti - boolean. Is user able to select one day or many. Can be changed on the fly
//methods:		display() - refreshes the calendar
//				changeMonth(newMonth)
//				changeYear(newYear)
//				incMonth() - increments month displayed and refreshes calendar. 
//				decMonth() - as above but decrement
//				incYear() - as above but increments year
//				decYear() - as above but decrements year
//				isInSelection(day,month,year) - returns true if supplied date is in the period selected
//				isSelected(day,month,year) - returns true if supplied date is the start or end date of selected period
//				noOfDaysSelected() - returns number of days currently selected
//
//Requires prototype.js and scriptaculous
// Oct 2006 Tom Elmore
function calendar(name, container, height, width, month, year){
	// id of this instance of calendar
	this.handle = name;
	
	//container size
	this.height = height;
	this.width = width;
	
	//set size of calendar
	container.style.height = height + 'px';
	container.style.width = width + 'px';
	
	//set size of each date block
	this.dayBoxWidth = Math.floor(Number(width)/7) - 2;
	this.dayBoxHeight = Math.floor(Number(height)/13)*2 - 2;
	this.headingBoxHeight = Math.floor(this.dayBoxHeight/2) - 2;
	this.fontSize = Math.round( Math.sqrt( Number(height)*Number(width) )/20 );
	
	//divider containing calendar
	this.container = container;
	this.container.style.cursor = 'default';
	
	//todays date info
	var now   = new Date();
	this.todaysMonth = now.getMonth();
	this.todaysYear  = now.getYear();
	if (this.todaysYear < 2000)  this.todaysYear = this.todaysYear + 1900; 
	
	//date currently being viewed info
	if(month > '') this.month = parseInt(month)-1;
	else this.month = this.todaysMonth;
	if(year > '') this.year = parseInt(year);
	else this.year = this.todaysYear;
	
	this.monthName = this.getMonthName(this.month);
	this.daysInMonth = null;
	
	//index 0 is days, 1 is months, 2 is years
	this.selectedStart = new Array(null,null,null);
	this.selectedEnd = new Array(null,null,null);
	
	//select single or multiple dates
	this.selectMulti = false;
}
calendar.prototype.display = function(){
	var i = 0;
	//number of days in the month
	this.daysInMonth = this.getDaysInMonth(this.month+1,this.year);
	//date of 1st day in the month
	var firstOfMonth = new Date (this.year, this.month, 1);
	//numeric value representing day of the week that firstOfMonth falls on
	var startingPos = firstOfMonth.getDay();
	//days becomes number of days since the sunday preceding the firstOfMonth
	var days = this.daysInMonth + startingPos;
	
	var headingStyle = "style='width:" + this.dayBoxWidth + "px; height:" + this.headingBoxHeight + "px; font-size:" + this.fontSize + "px;'"
	this.container.innerHTML = "<div class='dayHeadings' " + headingStyle + ">Sun</div><div class='dayHeadings' " + headingStyle + ">Mon</div><div class='dayHeadings' " + headingStyle + ">Tue</div><div class='dayHeadings' " + headingStyle + ">Wed</div><div class='dayHeadings' " + headingStyle + ">Thur</div><div class='dayHeadings' " + headingStyle + ">Fri</div><div class='dayHeadings' " + headingStyle + ">Sat</div>";
	
	//fill in remaining days of previous month with blank spaces
	var boxStyle = "style='width:" + this.dayBoxWidth + "px; height:" + this.dayBoxHeight + "px; font-size:" + this.fontSize + "px;'";
	for (i = 0; i < startingPos; i++) {
		this.container.innerHTML += "<div class='blankDay'" + boxStyle + "></div>";
	}
	
	//
	for (i = startingPos; i < days; i++) {
		//write date	
		day = i-startingPos+1;
		onClick = "onClick='" + this.handle + ".selectDate(" + day + "," + this.month + "," + this.year + ")'";
		this.container.innerHTML += "<div id='day" + day + "' class='day' " + boxStyle + onClick + " >" + day + "</div>";
	}
	
	//fill in remaining slots with blanks
	for (i=days; i<42; i++)  {
			this.container.innerHTML += "<div class='blankDay' " + boxStyle + "></div>";
	}
	
	//show anything already selected
	this.showSelection();
}
calendar.prototype.changeMonth = function(newValue){
	this.month = newValue;
	this.monthName = this.getMonthName(this.month);
	this.display();
}
calendar.prototype.changeYear = function(newValue){
	this.year = newValue;
	this.display();
}
calendar.prototype.getMonthName = function(index){
	switch(index){
		case 0: return 'January';
		break;
		case 1: return 'February';
		break;
		case 2: return 'March';
		break;
		case 3: return 'April';
		break;
		case 4: return 'May';
		break;
		case 5: return 'June';
		break;
		case 6: return 'July';
		break;
		case 7: return 'August';
		break;
		case 8: return 'Semptember';
		break;
		case 9: return 'October';
		break;
		case 10: return 'November';
		break;
		case 11: return 'December';
		break;
	}
}
calendar.prototype.getDaysInMonth = function(month,year){
	var days;
	if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)  days=31;
	else if (month==4 || month==6 || month==9 || month==11) days=30;
	else if (month==2)  {
	if (this.isLeapYear(year)) { days=29; }
	else { days=28; }
	}
	return (days);
}
calendar.prototype.isLeapYear = function(Year){
	if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) {
	return (true);
	} else { return (false); }
}
calendar.prototype.incMonth = function(){
	newMonth = this.month + 1;
	if(newMonth > 11){
		newMonth = 0;
		this.incYear();
	}
	this.changeMonth(newMonth);
}
calendar.prototype.incYear = function(){
	this.changeYear(this.year + 1);
}
calendar.prototype.decMonth = function(){
	newMonth = this.month - 1;
	if(newMonth < 0){
		newMonth = 11;
		this.decYear();
	}
	this.changeMonth(newMonth);
}
calendar.prototype.decYear = function(){
	this.changeYear(this.year - 1);
}
//method run when a date is clicked upon
calendar.prototype.selectDate = function(day,month,year){
	if(this.selectMulti){
		//multiselect mode
		this.multiSelect(day,month,year);
	}
	else{
		//single select mode
		this.selectedEnd[0] = null;
		this.selectedEnd[1] = null;
		this.selectedEnd[2] = null;
		
		this.singleSelect(day,month,year);
	}
}
calendar.prototype.multiSelect = function(day,month,year){
	var queryDate =  new Date(year,month,day);
	
	var start = new Date(this.selectedStart[2],this.selectedStart[1],this.selectedStart[0]);
	var end = new Date(this.selectedEnd[2],this.selectedEnd[1],this.selectedEnd[0]);
	
	var midDate = new Date(start.getTime() + (end - start)/2);
	
	if(day == this.selectedStart[0] && month == this.selectedStart[1] && year == this.selectedStart[2]){
		this.selectedStart[0] = null;
		this.selectedStart[1] = null;
		this.selectedStart[2] = null;
	}
	else if(day == this.selectedEnd[0] && month == this.selectedEnd[1] && year == this.selectedEnd[2]){
		this.selectedEnd[0] = null;
		this.selectedEnd[1] = null;
		this.selectedEnd[2] = null;
	}
	else{
		if(this.selectedStart[0] == null){
			this.selectedStart[0] = day;
			this.selectedStart[1] = month;
			this.selectedStart[2] = year;
		}
		else if(this.selectedEnd[0] == null){
			this.selectedEnd[0] = day;
			this.selectedEnd[1] = month;
			this.selectedEnd[2] = year;
		}
		else if(queryDate <= midDate){
			this.selectedStart[0] = day;
			this.selectedStart[1] = month;
			this.selectedStart[2] = year;
		}
		else{
			this.selectedEnd[0] = day; 
			this.selectedEnd[1] = month;
			this.selectedEnd[2] = year;
		}
	}
	
	//free memory
	start = null;
	end = null;
	midDate = null;
	
	//check that start is before end. if not swap them
	this.checkSelectedOrder();
	
	this.showSelection();
}
calendar.prototype.singleSelect = function(day,month,year){
	if(day == this.selectedStart[0] && month == this.selectedStart[1] && year == this.selectedStart[2]){
		this.selectedStart[0] = null;
		this.selectedStart[1] = null;
		this.selectedStart[2] = null;
	}
	else{
		this.selectedStart[0] = day;
		this.selectedStart[1] = month;
		this.selectedStart[2] = year;
	}

	this.showSelection();
}
calendar.prototype.showSelection = function(){

	if(this.selectedStart[0]==null&&this.selectedStart[1]==null&&this.selectedStart[2]==null) var startPointSet = false;
	else var startPointSet = true;

	if(this.selectedEnd[0]==null&&this.selectedEnd[1]==null&&this.selectedEnd[2]==null) var endPointSet = false;
	else var endPointSet = true;

		if(!startPointSet){
			if(endPointSet){
				//only end selected
				for(var i=1;i<=this.daysInMonth;i++){
					if(this.isSelected(i,this.month,this.year)) document.getElementById('day' + i).style.backgroundColor = '#FFDDCC';
					else document.getElementById('day' + i).style.backgroundColor = '#FFFFFF';
				}
				
			}
			//nothing selected
			else this.clearSelections();
		}
		else{
			if(endPointSet){
				//both selected
				for(var i=1;i<=this.daysInMonth;i++){
					if(this.isInSelection(i,this.month,this.year)){
						if(this.isSelected(i,this.month,this.year)) document.getElementById('day' + i).style.backgroundColor = '#FFDDCC';
						else document.getElementById('day' + i).style.backgroundColor = '#FFCCCC';
					}
					else document.getElementById('day' + i).style.backgroundColor = '#FFFFFF';
				}
				
			}
			else{ 
			//only start selected
				for(var i=1;i<=this.daysInMonth;i++){
					if(this.isSelected(i,this.month,this.year)) document.getElementById('day' + i).style.backgroundColor = '#FFDDCC';
					else document.getElementById('day' + i).style.backgroundColor = '#FFFFFF';
				}

			}
		}
}
calendar.prototype.clearSelections = function(){
	for(var i=1;i<=this.daysInMonth;i++){
		document.getElementById('day' + i).style.backgroundColor = '#FFFFFF';
	}
}
calendar.prototype.isInSelection = function(day,month,year){
	
			startDate = new Date(this.selectedStart[2],this.selectedStart[1],this.selectedStart[0]);
			endDate = new Date(this.selectedEnd[2],this.selectedEnd[1],this.selectedEnd[0]);
			queryDate = new Date(year,month,day);
			
			if(startDate <= queryDate && queryDate <= endDate){
				startDate = null;
				endDate = null;
				queryDate = null;
				return true;
			}
			else{
				startDate = null;
				endDate = null;
				queryDate = null;
				return false;
			}
}
calendar.prototype.isSelected = function(day,month,year){
	
			var queryDate = new Date(year,month,day);
			
			if(this.selectedStart[2] != null && this.selectedStart[1] != null && this.selectedStart[0] != null){
				//set upper and lower date objects to get around inoperable ==
				var startDateUpper = new Date(this.selectedStart[2],this.selectedStart[1],(this.selectedStart[0]+1));
				var startDateLower = new Date(this.selectedStart[2],this.selectedStart[1],(this.selectedStart[0]-1));
				
				if(startDateLower < queryDate && queryDate < startDateUpper) return true;
				
				//free memory
				startDateLower = null;
				startDateUpper = null;
			}
			
			if(this.selectedEnd[2] != null && this.selectedEnd[1] != null && this.selectedEnd[0] != null){
				//set date of start of selection. Set as one day after due to == not operable on date objects
				var endDateUpper = new Date(this.selectedEnd[2],this.selectedEnd[1],(this.selectedEnd[0]+1));
				var endDateLower = new Date(this.selectedEnd[2],this.selectedEnd[1],(this.selectedEnd[0]-1));
				if(endDateLower < queryDate && queryDate < endDateUpper){
					endDateUpper = null;
					endDateLower = null;
					queryDate = null;
					return true;
				}
				else{
					endDateUpper = null;
					endDateLower = null;
					queryDate = null;
					return false;
				}
			}
			
			//if both selected properties are null
			queryDate = null;
			return false;	
}
calendar.prototype.checkSelectedOrder = function(){
	var start = new Date(this.selectedStart[2],this.selectedStart[1],this.selectedStart[0]);
	var end = new Date(this.selectedEnd[2],this.selectedEnd[1],this.selectedEnd[0]);
	
	if(start > end){
		var tempDate = this.selectedStart;
		this.selectedStart = this.selectedEnd;
		this.selectedEnd = tempDate;
		tempDate = null;
	}
	
	start = null;
	end = null;
}
calendar.prototype.noOfDaysSelected = function(){
	
	if(this.selectedStart[2] != null && this.selectedStart[1] != null && this.selectedStart[0] != null){
		if(this.selectedEnd[2] != null && this.selectedEnd[1] != null && this.selectedEnd[0] != null){
			var start = new Date(this.selectedStart[2],this.selectedStart[1],this.selectedStart[0]);
			var end = new Date(this.selectedEnd[2],this.selectedEnd[1],this.selectedEnd[0]);
			
			milliseconds = end - start;
			days = Math.round((milliseconds / 86400000) + 1);
			
			start = null;
			end = null;
		}
		else{
			days = 1;
		}
	}
	else{
		if(this.selectedEnd[2] != null && this.selectedEnd[1] != null && this.selectedEnd[0] != null){
			days = 1;
		}
		else{
			days = 0;
		}
	}
	
	return days;
}
calendar.prototype.resize = function( newHeight, newWidth ){
	//set internal size
	this.height = newHeight;
	this.width = newWidth;
	
	//set new container size
	this.container.style.height = newHeight + 'px';
	this.container.style.width = newWidth + 'px';
	
	//set new size of each date block
	this.dayBoxWidth = Math.floor(Number(newWidth)/7) - 2;
	this.dayBoxHeight = Math.floor(Number(newHeight)/13)*2 - 2;
	this.headingBoxHeight = Math.floor(this.dayBoxHeight/2) - 2;
	this.fontSize = Math.round( Math.sqrt( Number(newHeight)*Number(newWidth) )/20 );
}



//object myPage contains height and width of window. Cross browser compatible.
// Access details via myPage.height  and   myPage.width
// Oct 2006 Tom Elmore
function pageInfo(){

	if( !(this.width = window.innerWidth) ){
		if( document.documentElement.clientWidth > 0 ) this.width = document.documentElement.clientWidth;
		else this.width = document.body.clientWidth;
	}

	if( !(this.height = window.innerHeight) ){
		if( document.documentElement.clientHeight > 0 ) this.height = document.documentElement.clientHeight;
		else this.height = document.body.clientHeight;
	}

}
myPage = new pageInfo;

