Function.prototype.inheritsFrom = function( parentClassOrObject ){ 
	if ( parentClassOrObject.constructor == Function ) 
	{ 
		//Normal Inheritance 
		this.prototype = new parentClassOrObject;
		this.prototype.constructor = this;
		this.prototype.parent = parentClassOrObject.prototype;
	} 
	else 
	{ 
		//Pure Virtual Inheritance 
		this.prototype = parentClassOrObject;
		this.prototype.constructor = this;
		this.prototype.parent = parentClassOrObject;
	} 
	return this;
}


function isArray(){
	
	if (typeof arguments[0] == 'object') {  
	var criterion = arguments[0].constructor.toString().match(/array/i); 
		return (criterion != null);
	}
	return false;
}


zcal = function(name, functionArray, errorId, errorCId){
	this.debug = false;
	this.errors ='';
	this.name = name;
	
	if(errorId && errorCId){
	this.debug = true;
		if('undefined' != document.getElementById(errorId)){
			this.errorHolder = document.getElementById(errorId);
		}
		else{
			alert('Your Error Holder is not a valid element');
		}
		if('undefined' != document.getElementById(errorCId)){
		this.errorButton = document.getElementById(errorCId);
			this.errorButton.onChangeThis = function(){
				//if(BBcalendar.errors != ''){
					alert(this.name);
				if(eval(this.name + ".errors != ''")){
					//BBcalendar.errorHolder.innerHTML = BBcalendar.errors;
					eval(this.name + '.errorHolder.innerHTML = ' + this.name + '.errors');
					//BBcalendar.errors ='';
					eval(this.name + '.errors = ""');
				}
				else{
					//BBcalendar.errorHolder.innerHTML = 'There are no errors to display';
					eval(this.name + '.errorHolder.innerHTML = "There are no errors to display"');
					//BBcalendar.errors = '';
					eval(this.name + '.errors=""');
				}
			}
		}
	}
	
	if('undefined' != document.getElementById(errorId)){
		this.errorContainer = document.getElementById(errorId);
	}
	
	this.errorDump = function(){
			if(this.errors != ''){
				this.errorHolder.innerHTML = this.errors;
				this.errors ='';
			}
			else{
				this.errorHolder.innerHTML = 'There are no errors to display';
				this.errors = '';
			}
	}
	
	this.Day ='';
	this.Month ='';
	this.Year ='';
	this.CalendarDate = '';
	
	this.MonthInt = new Array(1,2,3,4,5,6,7,8,9,10,11,12);
	this.MonthStr = new Array('01','02','03','04','05','06','07','08','09','10','11','12');
	this.MonthName = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
	this.MonthAbbreviation = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	this.WeekDayInt = new Array(1,2,3,4,5,6,7);
	this.WeekDayStr = new Array('01','02','03','04','05','06','07');
	this.DayInt = new Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31);
	this.DayStr = new Array('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31');
	this.DayName = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
	this.DayAbbreviation = new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	this.BBDate = new Array();
	
	
	this.SetMonth = function(month){
		var valid = false;
		for(var i = 0; i<this.MonthInt.length; i++){
			if(month == this.MonthInt[i]){
				this.Month = month;
				this.BBDate['monthInt'] = month;
				this.BBDate['monthStr'] = this.MonthStr[i];
				this.BBDate['monthName'] = this.MonthName[i];
				this.BBDate['monthAbbr'] = this.MonthAbbreviation[i];
				valid = true;
			}
		}
		if(valid){
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetMonth</strong><br />Could Not Set Month.  Month not valid.';
			}
		}
	}
	
	this.SetDay = function(day){
		var valid = false;
		for(var i = 0; i<this.DayInt.length; i++){
			if(day == this.DayInt[i]){
				this.Day = day;
				this.BBDate['dayInt'] = day;
				this.BBDate['dayStr'] = this.DayStr[i];
				this.BBDate['dayName'] = this.DayName[i];
				this.BBDate['dayAbbr'] = this.DayAbbreviation[i];
				this.BBDate['weekDayInt'] = this.WeekDayInt[i];
				this.BBDate['weekDayStr'] = this.WeekDayStr[i];
				valid = true;
			}
		}
		if(valid){
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetDay</strong><br />Could Not Set Day.  Day not valid.';
			}
		}
	}
	
	this.SetWeekDay = function(weekday){
		var valid = false;
		for(var i = 0; i<this.WeekDayInt.length; i++){
			if(weekday == this.WeekDayInt[i]){
				this.BBDate['dayName'] = this.DayName[i];
				this.BBDate['dayAbbr'] = this.DayAbbreviation[i];
				this.BBDate['weekDayInt'] = this.WeekDayInt[i];
				this.BBDate['weekDayStr'] = this.WeekDayStr[i];
				valid = true;
			}
		}
		if(valid){
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetWeekDay</strong><br />Could Not Set WeekDay.  Week Day Number not valid.';
			}
		}
	}
	
	
	this.SetYear = function(year){
		var valid = false;
		if(year != ''){
				this.Year = year;
				this.BBDate['year'] = year;
				this.BBDate['yearStr'] = year.toString();
				valid = true;
		}
		if(valid){
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetDay</strong><br />Could Not Set Day.  Day not valid.';
			}
		}
	}

	this.SetDate = function(sMonth,sDay,sYear,sWeekDay){
		this.errors = '';
		this.ClearDate();
		if(undefined != sMonth){
			this.SetMonth(sMonth);
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetDate SetMonth</strong> Month not valid.<br />';
			}
		}
		
		if(undefined != sDay){
			this.SetDay(sDay);
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetDate SetDay</strong> Day not valid.<br />';
			}
		}
		
		if('undefined' != sWeekDay){
			this.SetWeekDay(sWeekDay);
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetDate SetWeekDay</strong> WeekDay not valid.<br />';
			}
		}
		
		if(undefined != sYear){
			this.SetYear(sYear);
		}
		else{
			if(this.debug){
			this.errors += '<br /><strong>SetDate SetYear</strong> Year not valid.<br />';
			}
		}
		if(this.debug){
			this.errorDump();
		}
		
		if(this.errors == ''){
			this.date = this.BBDate['monthStr'] + '/' + this.BBDate['dayStr'] + '/' + this.BBDate['yearStr'];
				if(this.debug){
				  this.VarDump();
				}
			//BBcalendar_process_date_click();
		}
			//alert(this.BBDate['monthStr'] + '/' + this.BBDate['dayStr'] + '/' + this.BBDate['yearStr']);
	}
	
	this.ClearDate = function(){
		this.Month = '';
		this.Day = '';
		this.Year = '';
		this.date =''
		this.BBDate['monthInt'] = '';
		this.BBDate['monthStr'] = '';
		this.BBDate['monthName'] = '';
		this.BBDate['monthAbbr'] = '';
		this.BBDate['dayInt'] = '';
		this.BBDate['dayStr'] = '';
		this.BBDate['dayName'] = '';
		this.BBDate['dayAbbr'] = '';
		this.BBDate['weekDayInt'] = '';
		this.BBDate['weekDayStr'] = '';
	}
	
	this.VarDump = function(){
		if(this.debug){
		var junk = new Array();
			var string = '';
			var br = '<br />';
			junk.push(this.name + '.Month = ' + this.Month);
			junk.push(this.name + '.Day = ' + this.Day);
			junk.push(this.name + '.Year = ' + this.Year);
			junk.push(this.name + '.BBDate["monthInt"] = ' + this.BBDate['monthInt']);
			junk.push(this.name + '.BBDate["monthStr"] = ' + this.BBDate['monthStr']);
			junk.push(this.name + '.BBDate["monthName"] = ' + this.BBDate['monthName']);
			junk.push(this.name + '.BBDate["monthAbbr"] = ' + this.BBDate['monthAbbr']);
			junk.push(this.name + '.BBDate["dayInt"] = ' + this.BBDate['dayInt']);
			junk.push(this.name + '.BBDate["dayStr"] = ' + this.BBDate['dayStr']);
			junk.push(this.name + '.BBDate["dayName"] = ' + this.BBDate['dayName']);
			junk.push(this.name + '.BBDate["dayAbbr"] = ' + this.BBDate['dayAbbr']);
			junk.push(this.name + '.BBDate["weekDayInt"] = ' + this.BBDate['weekDayInt']);
			junk.push(this.name + '.BBDate["weekDayStr"] = ' + this.BBDate['weekDayStr']);
			
			for(var i=0; i<junk.length; i++){
				string += br + junk[i] + br;
			}
			this.errorHolder.innerHTML = string;
			
		}
	}
	
	this.Getdate = function(format){
		var return_date = '';
		var string ='';
		var regEx;
		var status;
		var mystring = format.toString();
		var myYear = this.Year.toString();
		var monthFormatKey = new Array('Month-Abbr','Month-Name','Month-String','Month-Integer');
		var monthFormatValue = new Array(this.BBDate['monthAbbr'],this.BBDate['monthName'].toString(),this.BBDate['monthStr'],this.BBDate['monthInt']);
	
		var dayFormatKey = new Array('Day-Abbr','Day-Name','Day-String','Day-Integer');
		var dayFormatValue = new Array(this.BBDate['dayAbbr'],this.BBDate['dayName'].toString(),this.BBDate['dayStr'],this.BBDate['dayInt']);
		
		var yearFormatKey = new Array('YYYY','YY');
		var yearFormatValue = new Array(myYear.slice(0,4),myYear.slice(2,4));
		
		if(this.Day != '' && this.Month != '' && this.Year != ''){
			
			for(var i = 0; i<monthFormatKey.length;i++){
				regEx = new RegExp(monthFormatKey[i], 'gi');
				mystring = mystring.replace(regEx, monthFormatValue[i]);
			}
			for(var i = 0; i<dayFormatKey.length;i++){
				regEx = new RegExp(dayFormatKey[i], 'gi');
				mystring = mystring.replace(regEx, dayFormatValue[i]);
			}
			
			for(var i = 0; i<yearFormatKey.length;i++){
				regEx = new RegExp(yearFormatKey[i], 'gi');
				mystring = mystring.replace(regEx, yearFormatValue[i]);
			}
			
		}
		return mystring;
	}
	
	this.buildData = function(){
		if(undefined != document.getElementById(this.name + '_build_data')){
			if(document.getElementById(this.name + '_build_data').innerHTML != ''){
			var string = document.getElementById(this.name + '_build_data').innerHTML;
			eval(string);
			}
			else{
				if(this.debug){
				this.errors += '<br /><strong>buildData</strong> No data json present.<br />';
				}
				else{
					document.getElementById(this.name + '_build_data').innerHTML = '';
				}
			}
		}
	}
	
	
	this.yearDDchange = functionArray["year_DD_change"];
	this.monthDDchange = functionArray["month_DD_change"];
	this.dateClick = functionArray["date_click"];
	
	this.getData = function(data_Sniffer){
		this.buildData();
		if(undefined != eval(this.name + '_data_Obj')){
			var obj = eval(this.name + '_data_Obj');
			var sobj = eval(data_Sniffer);
			var keyStatus = false;
			var error_array = new Array();
			if(this.name){
				var string = '';
				var searchStatus = '';
				var mystring = '';
				var c = 0;
				var d = 0;
				var return_data_Obj = {"records" : [], "count" : ""};
				var value_array = new Array();
				for(var i=0; i<obj.records.length; i++){
					c = 0;
					searchStatus = true;
					for(var ii=0; ii<sobj.records.length; ii++){
						if(searchStatus){
							string = 'obj.records[i].' + sobj.records[ii].name + ' == "' + sobj.records[ii].value + '"';
							if(eval(string)){
							c = c + 1;
								searchStatus = true;
							}
							else{
								searchStatus = false;
							}
							//alert('search status ' + searchStatus + ' row ' + i + ' name ' + sobj.records[i].name);
							if(c == sobj.records.length){
								d = d + 1;
								return_data_Obj.records.push(obj.records[i]);
							}
						}
					}
				}
			}
			return_data_Obj.count = d;
			return return_data_Obj;
		}
		else{
			alert('problem');
		}
		
	}
		
}


function zcalendar(name,eid,ebid){
// to set debug mode provide an error message container id and an error message button id
	var functionArray = new Array();
	functionArray["year_DD_change"] = function(){
		alert('year_DD_change');
	}
	functionArray["month_DD_change"] = function(){
		alert('month_DD_change');
	}
	functionArray["date_click"] = function(type){
		alert(type);
		alert('date_click');
	}
	if('undefined' != eid && 'undefined' != ebid){
	BBcalendar = new zcal(name,functionArray,eid,ebid);
	}
	else{
	BBcalendar = new zcal(name,functionArray);
	}
}

/*Example zcal object as BBcalendar = new zcal(name,functionArray,eid,ebid);
BBcalendar Methods
BBcalendar.Getdate(String)
	Getdate String Options
		Month Options --  'Month-Abbr','Month-Name','Month-String','Month-Integer'
		Month Returns Ex. 'Jan',	   'January',	'01',		    1
		Day	  Options --  'Day-Abbr',  'Day-Name',  'Day-String',  'Day-Integer'
		Day   Returns Ex. 'Tue',	   'Tuesday',   '03',		,   3
		Year  Options --  'YYYY',	   'YY'
		Year  Returns Ex. '2001',	   '01'
	Getdate Example
			BBcalendar.Getdate('My date is Day-Name Month-Name Day-String , YYYY')
			Returns 'My date is Tuesday January 03 , 2001'
			
BBcalendar.getData(data_retrieval_object)
	data retrieval object example: myObject

BBcalendar.ClearDate()
Clears all date properties

BBcalendar.SetYear(year)
Sets all year properties based upon year value passed

BBcalendar.SetDay(day)
Sets all day properties based upon day number passed

BBcalendar.SetMonth(Month)
Sets all month properties based upon month number passed

BBcalendar.SetWeekDay(day)
Sets all week day properties based upon week day number passed

BBcalendar.SetDate(month,day,year,weekday)
Sets all date properties based upon month number, day number, year and week day number passed
			
BBcalendar Properties set by date click (with example values)
	BBcalendar.Month = 5
	
	BBcalendar.Day = 3
	
	BBcalendar.Year = 2007
	
	BBcalendar.BBDate["monthInt"] = 5
	
	BBcalendar.BBDate["monthStr"] = 05
	
	BBcalendar.BBDate["monthName"] = May
	
	BBcalendar.BBDate["monthAbbr"] = May
	
	BBcalendar.BBDate["dayInt"] = 3
	
	BBcalendar.BBDate["dayStr"] = 03
	
	BBcalendar.BBDate["dayName"] = Thursday
	
	BBcalendar.BBDate["dayAbbr"] = Thu
	
	BBcalendar.BBDate["weekDayInt"] = 5
	
	BBcalendar.BBDate["weekDayStr"] = 05
	
	External Drop Down Elements for Month and Year are accessed by the following ids BBcalendar_month_selector and BBcalendar_year_selector
	*/


