/**
/*  dateselect.js - requires events.js, element.js, animation.js
/*  allows for date selection using visial calendar interface, returns date in specified string format. 

/*  Ben Ipsen  2006. No Copyright. No license. Just Love. 
/*  Use wisely and for the greater good.  
/*
/*  docs: http://benipsen.com/elementary/
**/

//non ie dates require addition of 1900 for some awesome reason

 var yearAdd = (navigator.appName.indexOf("xplorer")  > 0) ? 0 : 1900;

function DateRangeSelector(begin, end, range, backwards, bopen, eopen ){ 
	  if(!bopen) bopen = document.getElementById("openCalStart");
	  if(!eopen) eopen = document.getElementById("openCalEnd");
	  var begins = new DateSelector(begin.field, begin.format, begin.hidden, begin.hiddenFormat, begin.defaultValue, backwards, 0, bopen);
	  var endDate = new Date(begin.defaultValue.getYear()+yearAdd, begin.defaultValue.getMonth(), begin.defaultValue.getDate()+range);
	  var ends = new DateSelector(end.field, end.format, end.hidden, end.hiddenFormat, endDate, false, range, eopen);

	  ends.rangeSet = false;  
	  var rng = range;
	  
	 
	 ends.setRangeDate(rng, begins, true);
	 
	 this.setUpRange = function(){   
		if(!ends.rangeSet){
		  ends.setRangeDate(rng, begins);
		  ends.rangeSet = true;
		} else if( begins.date.format("yyyymmdd") >= ends.date.format("yyyymmdd")){
		   ends.setRangeDate(rng, begins);
		   ends.rangeSet = true;  
		} else {
		   document.getElementById(ends.name + "_" + (begins.date.getYear()+yearAdd)+'_'+begins.date.getMonth()+'_'+begins.date.getDate()).className = 'calendarDayRange';
		}
	 }
	 begins.addListener(this.setUpRange);
}

function DateSelector(field, format, hidden, hiddenFormat, defaultValue, allowBackwards, rangeMin, button){
 
	var This = this;
	    var range = rangeMin ? rangeMin : 0; 
		//public props
		This.field = field;
		This.element = null;   
		This.format = format ? format : "yyyy-mm-dd";
		This.hidden = hidden ? hidden : false;
		This.hiddenFormat = hiddenFormat ? hiddenFormat : false;
		This.date = new Date(); 
		This.today = new Date();
	    This.day = This.date.getDate();
 	    This.name = This.field.getAttribute("name") + "_" + This.field.form.getAttribute("name");       
		This.value = This.field.getAttribute("value");
        This.allowBack = allowBackwards ? allowBackwards : false;
		This.button = button ? button : This.field;
	    if(defaultValue){
			This.date = new Date(defaultValue.getYear()+yearAdd, defaultValue.getMonth(), defaultValue.getDate());
		}           
		This.current = This.date;
	
	this.open = function(e){
   		This.cal.effect({width:size*133,height:160,duration:0.3,fps:1/24,trans:physics.easeOut}); 
	}
	                                                   
	this.keyClose = function(e){
		This.cal.effect({width:0,height:0,duration:0.3,fps:1/24,trans:physics.easeOut}); 
	}
	this.close = function(e){
		 var ei = new EventInfo(e, true); 
		 var left = This.cal.element.getRealLeft() - 20;
		 var top = This.cal.element.getRealTop() - 20;  
		 if(   ( ei.xmouse < left  || ei.xmouse > (left + This.cal.element.getRealWidth() + 20) )
		    || ( ei.ymouse < top   || ei.ymouse > (top + This.cal.element.getRealHeight() + 30) )
		 	){    
		 	if(ei.source != This.button && ei.source != forward && ei.source != back && ei.source != This.cal){
	  	 		This.cal.effect({width:0,height:0,duration:0.3,fps:1/24,trans:physics.easeOut});
			}
		}
	  return true;
	}   
	
	this.expand = function(){
		if(size < 4){
			size++;  
			This.current = new Date(This.current.getYear()+yearAdd, This.current.getMonth()+1, This.current.getDate());
			if(document.getElementById(This.name + "_month_" + (This.current.getYear() + yearAdd).toString() + "_" + (This.current.getMonth()).toString()) == null){		
			  This.appendMonth(This.current.getYear()+yearAdd, This.current.getMonth());
			}
			This.cal.effect({width:(size*134),height:160,duration:0.3,fps:1/24,trans:physics.easeOut});   
		}
	}   
    this.collapse = function(){
		if(size > 1){			
			size--;
			This.cal.effect({width:(This.cal.element.getRealWidth()-134),height:160,duration:0.3,fps:1/24,trans:physics.easeOut});   
		}  
	}
	
	   this.forward = function(){                              
	 	var tx = (This.slide.element.x-134);   
		This.current = new Date(This.current.getYear()+yearAdd, This.current.getMonth()+1, 1);
		if(document.getElementById(This.name + "_month_" + (This.current.getYear() + yearAdd).toString() + "_" + (This.current.getMonth()).toString()) == null){		
	      This.appendMonth(This.current.getYear()+yearAdd, This.current.getMonth());
		}
		This.slide.effect({y:0,x:tx,duration:0.3,fps:1/24,trans:physics.easeOut});   
		
	}
	
	this.back = function(){  
		var tx = (This.slide.element.x+134);
	    var month = (This.current.getMonth()-1);
		var year = This.current.getYear();
		if(month == -1){ month = 11; year--; } 
	    This.current = new Date(year+yearAdd, month, This.current.getDate());
	    if(document.getElementById(This.name + "_month_" + (This.current.getYear() + yearAdd).toString() + "_" + (month).toString()) == null){
		   tx = (This.slide.element.x);   
		   This.slide.element.setPosition(This.slide.element.x-134);
		   This.prependMonth(This.current.getYear()+yearAdd, This.current.getMonth());
		}
		This.slide.effect({y:0,x:tx,duration:0.3,fps:1/24,trans:physics.easeOut});
	}   
	this.currentRangeTag = false;
	this.setRangeDate = function(range, begins, nodraw){
		 
		 This.cal.element.remove(document.getElementById("calslide_" + This.name)); 
		 var slide = This.cal.element.append("div");
				 slide.style.position = 'absolute';
				 slide.className = 'calendarSlide';   
				 slide.setAttribute("id","calslide_" + This.name);
		
		This.slide = new Animation(slide, { x:0, y:0 }); 
		This.today = new Date(begins.date.getYear()+yearAdd, begins.date.getMonth(), begins.date.getDate());
		This.date = new Date(begins.date.getYear()+yearAdd, begins.date.getMonth(), begins.date.getDate()+range);		
		This.current = This.date;
		This.draw(This.date.getYear(),This.date.getMonth(), This.date.getDate()); 
		//append next month if we'll be spanning a gap in the range
		if(begins.date.getYear() < This.date.getYear() || begins.date.getMonth() < This.date.getMonth()){
			This.prependMonth(begins.date.getYear()+yearAdd, begins.date.getMonth(), false);
			var tx = (This.slide.element.x-134);
			This.slide.element.setPosition(tx,0);
		}
		This.field.value = This.date.format(This.format); 
		if(This.currentRangeTag){
			 This.currentRangeTag.className = 'calendarDay';
		}
		This.currentRangeTag = document.getElementById(This.name + "_" + (begins.date.getYear()+yearAdd)+'_'+begins.date.getMonth()+'_'+begins.date.getDate());
		document.getElementById(This.name + "_" + (begins.date.getYear()+yearAdd)+'_'+begins.date.getMonth()+'_'+begins.date.getDate()).className = 'calendarDayRange';
	}
	
	this.select = function(e){
		var ei = new EventInfo(e,true);
		var str = ei.source.getAttribute("id");
		var arr = str.split("_"); 
		var year = arr[2]
		var month = arr[3];
		var day = arr[4];  
	    var off = arr[5];
		
		//remove selected date
	  	if(document.getElementById(This.name + "_" + (This.date.getYear()+yearAdd) + '_' + This.date.getMonth() + "_" + This.date.getDate()))
				document.getElementById(This.name + "_" + (This.date.getYear()+yearAdd) + '_' + This.date.getMonth() + "_" + This.date.getDate()).className = 'calendarDay';
	    document.getElementById(This.name + "_" + year + '_' + month + "_" + day).className = 'calendarDaySelected';
		    
		This.date = new Date(year, month, day);
		var formatted = This.date.format(This.format);
		This.field.value = formatted;
		This.keyClose();        
		if(off){
		   	This.slide.effect({x:(This.date.getMonth()*-134),y:0});
		} 
		//broadcast the event 
		for(var l=0; l < listeners.length; l++){
			listeners[l].call(This);
		}
	}  
	
	this.addListener = function(call){
		listeners.push(call);
	}
	
	this.draw = function(year, month, date, sday){   
	    This.appendMonth(yearAdd + year, month, sday);
	}  
	 
	this.appendMonth = function(year, month, sday){ 
	    var monthe = This.slide.element.append("div");   
			monthe.setAttribute("id",This.name + "_month_" + year + "_" + month);
			monthe.className="calendarMonth";
			monthe = new Element(monthe,{});        
	    var label = monthe.append('p', months[month] + ' ' + year);
		var grid = monthe.append('div'); 
		This.drawMonth(year, month, grid, sday);
		This.slide.element.setDimensions(This.slide.element.width+135,This.slide.element.getRealHeight());
		return monthe;		    
	}     
	
	this.prependMonth = function(year, month, sday){        
		var before = This.lastDrawnElement;
	    var monthe = This.slide.element.prepend("div", before); 
			monthe.setAttribute("id",This.name + "_month_" + year + "_" + month);
			monthe.className="calendarMonth";
			monthe = new Element(monthe,{});  
			 
	    var label = monthe.append('p', months[month] + ' ' + year);
		var grid = monthe.append('div'); 
		This.drawMonth(year, month, grid, sday);
		This.slide.element.setDimensions(This.slide.element.width+135,This.slide.element.getRealHeight());
	  	
		return monthe;      
	}
	
	this.drawMonth = function(year, month, grid, sday){
	    var s = "";       
	    var first = new Date(year, month, 1);
		var offset = first.getDay()-1; 
	    var grid = new Element(grid,{});
	    for(var d=0; d < 7; d++){
		  	var lbl = grid.append('span',days[d]); 
			    lbl.className='dayLabel';
		}
		  
	   for(var i = 0; i < 42; i++){     
		  var day = new Date(year, month, i-offset); 
		  var disabled = false; 
		  var className = day.getMonth() == month ? "calendarDay" : "calendarDayOffMonth";
		  var id = day.getMonth() == month ? This.name + '_'+year+'_'+day.getMonth()+'_'+day.getDate() : This.name + '_'+year+'_'+day.getMonth()+'_'+day.getDate()+'_off';
		  if(day.getMonth() == This.date.getMonth() && This.date.getDate() == day.getDate() && className != "calendarDayOffMonth"){
				className = 'calendarDaySelected';
		  }  
		 
		 var adjusted = new Date(This.date.getYear()+yearAdd, This.date.getMonth(), This.date.getDate()-range);
		 if(!This.allowBack && day.format("yyyymmdd") < adjusted.format("yyyymmdd")){		     
		   		className = 'calendarDayDisabled'; 
				disabled = true;
		  }
	      var _day = grid.append('a', day.getDate());
			  _day.setAttribute("id", id);
			  _day.className=className;	   
			  if(!disabled){ 
				  _day.style.cursor = "pointer";
				  _day.setAttribute("href","javascript:void(0)");
				  _day.onclick = This.select;    
			  } 
	   } 
	}  
    
	var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
	var days = ["S","M","T","W","T","F","S"]; 
	
 	var cal = document.createElement("div");  

		cal.style.position = 'absolute';
		//cal.style.top = This.field.offsetTop + This.field.offsetHeight + 'px';
		//cal.style.left = This.field.offsetLeft + 'px';
		if (navigator.appName.indexOf("xplorer")  > 0) cal.style.left = This.field.offsetLeft - 8 + 'px';	//rxb
        This.field.parentNode.appendChild(cal);
		cal.setAttribute("id","cal_" + This.name);  
		This.cal = new Animation(cal, { width:0, height:0 });
		This.cal.element.setDimensions(0,0);
		This.cal.element.setClass('calendarWindow');
		
     var slide = This.cal.element.append("div");
		 slide.style.position = 'absolute';
		 slide.className = 'calendarSlide';   
		 slide.setAttribute("id","calslide_" + This.name);
		 This.slide = new Animation(slide, { x:0, y:0 });  

	This.draw(This.date.getYear(),This.date.getMonth(), This.date.getDate(), true); 
	
	 //draw size controller
		var size = 1;
		var controls = This.cal.element.append("div");
			controls.className = 'calendarControls';   
			controls = new Element(controls);   
			/*var smaller = controls.append("a",'-');
				smaller.className = 'smaller';  
				smaller.onclick = This.collapse; 
				smaller.setAttribute("href","javascript:void(0)");   
	  		var bigger = controls.append("a",'+');
				bigger.className = 'bigger';
	 			bigger.onclick = This.expand;
				bigger.setAttribute("href","javascript:void(0)");*/   
			var back = controls.append("a",'&laquo; last');
				back.className = 'back'; 
				back.onclick = This.back;  
			var forward = controls.append("a",'next &raquo;');
				forward.className = 'forward';
	  	        forward.onclick = This.forward;
		    
		  
	//set up some event handlers and listener array for selector events
	//This.button.onfocus = This.open;
	This.button.onclick = This.open;  
	This.field.onblur = This.close;
	addWindowEventListener('mouseup', this.close);
	//keyListener.addKey(9,This.keyClose); 
	var formatted = This.date.format(This.format);
	This.field.value = formatted;
	var listeners = new Array();
	
} 

   
function zero(str){ 
	if(str < 10){
		return '0' + str;
	} else {
		return str;
	}                    
	
}
Date.prototype.format = function(f)
{
    if (!this.valueOf())
        return '&nbsp;';

    var d = this;

    return f.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
        function($1)
        {
            switch ($1.toLowerCase())
            {
            case 'yyyy': return d.getFullYear();
            case 'mm':   return zero(d.getMonth() + 1);
            case 'dd':   return zero(d.getDate());
         
            }
        }
    );
}