Object.extend(Date.prototype, {
	defaultFormat:'dd.mm.yyyy HH:nn:ss',
	shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
	longMonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
	shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
	longDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
	formatFuncArray: ['dd','d','DD','D','mm','m','MM','M','yyyy','yy','a','A','hh','h','HH','H','nn','ss'],
	monthDays:[31,28,31,30,31,30,31,31,30,31,30,31],
	dayListSource:'/servlet/workingdayscount.asp',
	objXML:null,
	format:function(formatStr){
		var returnStr = formatStr;
		var formatArray = new Array();
		var curFunc='';
		for (var i = 0; i < this.formatFuncArray.length; i++){
			curFunc = this.formatFuncArray[i];
			if (this[curFunc]){
				var findFuncExp = new RegExp(curFunc, "g");
				if(findFuncExp.test(returnStr)){
					formatArray.push(curFunc);
				}
				returnStr = returnStr.replace(findFuncExp, '~');
			}
		}
		returnStr = formatStr;
		for (var i = 0; i < formatArray.length; i++) {
			curFunc = formatArray[i];
			if (this[curFunc]){
				var findFuncExp = new RegExp(curFunc, "g");
				returnStr = returnStr.replace(findFuncExp, curFunc+'_');
			}
		}
		for (var i = 0; i < formatArray.length; i++) {
			curFunc = formatArray[i];
			if (this[curFunc]){
				var findFuncExp = new RegExp(curFunc+'_', "g");
				returnStr = returnStr.replace(findFuncExp, this[curFunc].apply(this));
			}
		}
		return returnStr;
	},
	dateDiff:function(type, diffDateTime){
		var smallDate, bigDate, diffSign;
		smallDate = diffDateTime.getTime()>=this.getTime() ? this : diffDateTime;
		bigDate = diffDateTime.getTime()>this.getTime() ? diffDateTime : this;
		diffSign = diffDateTime.getTime()>=this.getTime() ? 1 : -1;
		var ret=diffDateTime.getTime()-this.getTime();//diff in miliseconds
		if (type=='y'){
			ret = diffDateTime.getFullYear()-this.getFullYear();
		}else if (type=='m'){
			ret = diffDateTime.getFullYear()-this.getFullYear();
			ret += (diffDateTime.getMonth()+(ret*11))-this.getMonth();
		}else if (type=='d'){
			var yearDiff = bigDate.getFullYear()-smallDate.getFullYear(); 
			//DebugWindow('Date.dateDiff:yearDiff', yearDiff);
			var leapYear = Math.floor(bigDate.getFullYear() / 4) - Math.floor(smallDate.getFullYear() / 4);
			//DebugWindow('Date.dateDiff:leapYear', leapYear);
			ret = 365 * yearDiff;
			ret += leapYear;
			if(!yearDiff){
				for(var i=0;i<smallDate.getMonth();i++) ret -= this.monthDays[i];
				for(var i=0;i<bigDate.getMonth();i++) ret += this.monthDays[i];
			}else{
				for(var i=smallDate.getMonth();i<bigDate.getMonth();i++) ret += this.monthDays[i];
			}
			//DebugWindow('Date.dateDiff:ret', ret);
			ret = ret - smallDate.getDate() + bigDate.getDate();
			//DebugWindow('Date.dateDiff:ret', ret);
			ret = ret * diffSign;
		}else if (type=='wd'){
			ret = this.getWorkingDaysCount(diffDateTime);
		}else if (type=='h'){
			var daycount = this.dateDiff('d', diffDateTime);
			ret = daycount * 24 * diffSign;
			ret = ret - smallDate.getHours() + bigDate.getHours();
			ret = ret * diffSign;
		}else if (type=='n'){
			var hourcount = this.dateDiff('h', diffDateTime);
			ret = hourcount * 60 * diffSign;
			ret = ret - smallDate.getMinutes() + bigDate.getMinutes();
			ret = ret * diffSign;
		}else if (type=='s'){
			var minutecount = this.dateDiff('n', diffDateTime);
			ret = minutecount * 60 * diffSign;
			ret = ret - smallDate.getSeconds() + bigDate.getSeconds();
			//DebugWindow('diffDateTime:smallDate.getSeconds()', smallDate.getSeconds());
			//DebugWindow('diffDateTime:bigDate.getSeconds()', bigDate.getSeconds());
			ret = ret * diffSign;
		}
		return ret;
	},
	getWorkingDaysCount:function(diffDateTime){

		if(diffDateTime.getTime()<this.getTime()) return 0;

		this.objXML = null;

		if(window.XMLHttpRequest){
			this.objXML = new XMLHttpRequest(); 
		} else if (window.ActiveXObject){
			this.objXML = new ActiveXObject("Microsoft.XMLHTTP");
		}
		
        var surl = '';
		surl = window.location.protocol + '//' + window.location.hostname + this.dayListSource + '?d1='+this.format('dd.mm.yyyy')+'&d2=' + diffDateTime.format('dd.mm.yyyy');
		//DebugWindow('getWorkingDaysCount:surl', surl);
		this.objXML.open("GET", surl, false);
		this.objXML.setRequestHeader("Accept-Charset", "windows-1254");
		this.objXML.setRequestHeader("Accept-Language", "tr");
		if(!MS.Browser.isIE) this.objXML.setRequestHeader("Connection", "close");
		this.objXML.send(null);

		if(this.objXML.status != 200) return 0; 

		if(this.objXML.responseXML==null || this.objXML.responseXML.documentElement == null) return 0; 

		var doc = this.objXML.responseXML.documentElement;
		var nodes = doc.getElementsByTagName("element");

		if(nodes.length == 0) return 0;
		return parseFloat(nodes[0].firstChild.data);
	},
	getWorkingDayAfter:function(diff){
		if (diff<=0) return this;

		this.objXML = null;

		if(window.XMLHttpRequest){
			this.objXML = new XMLHttpRequest(); 
		} else if (window.ActiveXObject){
			this.objXML = new ActiveXObject("Microsoft.XMLHTTP");
		}
		
        var surl = '';
		surl = window.location.protocol + '//' + window.location.hostname + this.dayListSource + '?d1='+this.format('dd.mm.yyyy')+'&f=' + diff;
		//DebugWindow('getWorkingDayAfter:surl', surl);
		this.objXML.open("GET", surl, false);
		this.objXML.setRequestHeader("Accept-Charset", "windows-1254");
		this.objXML.setRequestHeader("Accept-Language", "tr");
		if(!MS.Browser.isIE) this.objXML.setRequestHeader("Connection", "close");
		this.objXML.send(null);

		if(this.objXML.status != 200) return this; 

		if(this.objXML.responseXML==null || this.objXML.responseXML.documentElement == null) return this; 

		var doc = this.objXML.responseXML.documentElement;
		var nodes = doc.getElementsByTagName("element");

		if(nodes.length == 0) return this;
		this.setFormatted(nodes[0].firstChild.data, 'dd.mm.yyyy');
	},
	dateAdd:function(type, diff){
		//var ret = diff;
		diff = parseFloat(diff);
		switch(type)
		{
			case 'y':
				this.setFullYear(this.getFullYear()+diff);
				//ret = diff * 365 * 24 * 60 * 60 * 1000; 
				break;
			case 'm':
				this.setMonth(this.getMonth()+diff);
				/*
				ret = 0;
				var i=0;
				while (i<diff)
				{
					ret = ret + this.monthDays[(i+this.getMonth())%12];
					i++;
				}
				ret = ret * 24 * 60 * 60 * 1000; 
				*/
				break;
			case 'd':
				this.setDate(this.getDate()+diff);
				break;
				//ret = ret * 24; 
			case 'wd':
				this.getWorkingDayAfter(diff);
				break;
			case 'h':
				this.setHours(this.getHours()+diff);
				break;
				//ret = ret * 60; 
			case 'n':
				this.setMinutes(this.getMinutes()+diff);
				break;
				//ret = ret * 60; 
			case 's':
				this.setSeconds(this.getSeconds()+diff);
				break;
				//ret = ret * 1000; 
		}
		return this;
	},
	dayOfYear:function(){
		var ret=0;
		for(var i=0;i<this.getMonth();i++) ret += monthDays[i];
		ret += this.getYear() % 4 ? 1 : 0;
		ret += this.getDate();
	},
	getFormatted:function(){
		return this.format(this.defaultFormat);
	},
	setFormatted:function(dateString, formatStr){
		if (dateString=='' || formatStr=='') return this;
		var formatDelimeters = new Array();
		if(formatStr.indexOf('~')>=0) formatDelimeters.push('~');
		var formatArray = new Array();
		var tmp_formatStr = formatStr;

		//kullanılan format parametrelerini belirle
		for(var i = 0; i< this.formatFuncArray.length;i++){
			var findFuncExp = new RegExp(this.formatFuncArray[i], "g");
			if(findFuncExp.test(tmp_formatStr)){
				formatArray.push(this.formatFuncArray[i]);
				tmp_formatStr = tmp_formatStr.replace(findFuncExp, '~');
			}
		}
		//~ çıkar ki sadece ayıraçlar ve ekstra işaretler kalsın
		tmp_formatStr = tmp_formatStr.replace(/~/g,'');
		formatDelimeters.push('.');
		formatDelimeters.push(':');
		formatDelimeters.push('/');
		formatDelimeters.push(' ');
		for(var i=0;i<tmp_formatStr.length;i++){
			if(formatDelimeters.indexOf(tmp_formatStr.substr(i,1))<0) formatDelimeters.push(tmp_formatStr.substr(i,1));
		}
		tmp_formatStr = formatStr;
		//format parametrelerinin değerlerini çöz
		for(var i=0;i<formatArray.length;i++){
			var index=tmp_formatStr.indexOf(formatArray[i]);
			while(index>=0){
				var j;
				j=dateString.indexOfNearest(formatDelimeters, index+1);
				if(j<0) j = dateString.length;
				if(this['inverse_'+formatArray[i]]) {
					//DebugWindow('found inverse f', true);
					//DebugWindow('index', index);
					//DebugWindow('j', j);
					//DebugWindow('this[inverse_'+formatArray[i]+'].apply(this, '+dateString.substr(index,j-index)+')', this['inverse_'+formatArray[i]].apply(this, dateString.substr(index,j-index)));
					while (j>index && !this['inverse_'+formatArray[i]].apply(this, [dateString.substr(index,j-index)])){
						//DebugWindow('set inverse f', 'inverse_'+formatArray[i]+'('+dateString.substr(index,j-index)+')');
						//DebugWindow('index', index);
						//DebugWindow('j', j);
						//DebugWindow('setFormatted:inverse_'+formatArray[i], this['inverse_'+formatArray[i]]);
						//DebugWindow('this', this);
						j--;
					}
					if(j>index) 
					{
						//DebugWindow('setFormatted:dateString.substr(index,j-index)', dateString.substr(index,j-index));
						tmp_formatStr = tmp_formatStr.replace(formatArray[i],String.repeat('^',j-index));
					} else 
					{
						throw new Error('Format Error!!');
					}
				}
				index=tmp_formatStr.indexOf(formatArray[i]);
			}
		}
		//DebugWindow('setFormatted:formatStr', formatStr);
		//DebugWindow('setFormatted:dateString', dateString);
		//DebugWindow('setFormatted:tmp_formatStr', tmp_formatStr);
		return this;
	},
	// Day
	d: function() { return this.getDate(); },
	inverse_d: function(value) { this.setDate(value); return true;},
	dd: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); },
	inverse_dd: function(value) { 
		//DebuWindow('value', value);
		//DebugWindow('parseFloat(arguments[0])', parseFloat(arguments[0]));
		this.setDate(parseFloat(value)); 
		return true;
	},
	D: function() { return this.shortDays[this.getDay()]; },
	//j: function() { return this.getDate(); },
	//l: function() { return this.longDays[this.getDay()]; },
	DD: function() { return this.longDays[this.getDay()]; },
	//N: function() { return this.getDay() + 1; },
	//S: function() { return (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th'))); },
	//w: function() { return this.getDay(); },
	//z: function() { return "Not Yet Supported"; },
	// Week
	//W: function() { return "Not Yet Supported"; },
	// Month
	//F: function() { return this.longMonths[this.getMonth()]; },
	m: function() { return this.getMonth() + 1; },
	inverse_m: function(value){ this.setMonth(value-1); return true;},
	mm: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
	inverse_mm: function(value) { this.setMonth(parseFloat(value)-1);  return true;},
	M: function() { return this.shortMonths[this.getMonth()]; },
	inverse_M: function(value) { if(this.shortMonths.indexOf(value)>=0){this.setMonth(this.shortMonths.indexOf(value));}else{return false;} return true; },
	MM: function() { return this.longMonths[this.getMonth()]; },
	inverse_MM: function(value) { if(this.longMonths.indexOf(value)>=0){this.setMonth(this.longMonths.indexOf(value));}else{return false;} return true;},
	//n: function() { return this.getMonth() + 1; },
	//t: function() { return "Not Yet Supported"; },
	// Year
	//L: function() { return "Not Yet Supported"; },
	//o: function() { return "Not Supported"; },
	//Y: function() { return this.getFullYear(); },
	yyyy: function() { return this.getFullYear(); },
	inverse_yyyy: function(value) { this.setFullYear(value); return true;},
	yy: function() { return ('' + this.getFullYear()).substr(2); },
	inverse_yy: function(value) {
		if(parseFloat(value)>50) this.setFullYear('19' + value); else this.setFullYear('20' + value);
		return true;
	},
	// Time
	a: function() { return this.getHours() < 12 ? 'am' : 'pm'; },
	A: function() { return this.getHours() < 12 ? 'AM' : 'PM'; },
	//B: function() { return "Not Yet Supported"; },
	h: function() { return this.getHours() % 12 || 12; },
	inverse_h: function(value){this.setHours(value);return true;},
	hh: function() { return ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12); },
	inverse_hh: function(value){this.setHours(parseFloat(value));return true;},
	H: function() { return this.getHours(); },
	inverse_H: function(value){this.setHours(value);return true;},
	HH: function() { return (this.getHours() < 10 ? '0' : '') + this.getHours(); },
	inverse_HH: function(value){this.setHours(parseFloat(value));return true;},
	//i: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
	nn: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
	inverse_nn: function(value) { this.setMinutes(parseFloat(value)); return true;},
	ss: function() { return (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(); },
	inverse_ss: function(value) { this.setSeconds(parseFloat(value)); return true;}
	// Timezone
	//e: function() { return "Not Yet Supported"; },
	//I: function() { return "Not Supported"; },
	//O: function() { return (this.getTimezoneOffset() < 0 ? '-' : '+') + (this.getTimezoneOffset() / 60 < 10 ? '0' : '') + (this.getTimezoneOffset() / 60) + '00'; },
	//T: function() { return "Not Yet Supported"; },
	//Z: function() { return this.getTimezoneOffset() * 60; },
	// Full Date/Time
	//c: function() { return "Not Yet Supported"; },
	//r: function() { return this.toString(); },
	//U: function() { return this.getTime() / 1000; }
}, false); 