/*
	Collection of utility functions
 */
SG.namespace("SG.cal.util");

SG.cal.util = {
	isEmpty : function(string) {
		return ((string == null) || (string.length == 0));
	},
	
	isNotEmpty : function(string) {
		return !SG.cal.util.isEmpty(string);
	},

	isBoolean : function(o) {
		return typeof o === 'boolean';
	},

	isFunction : function(o) {
		return typeof o === 'function';
	},

	isNull : function(o) {
		return o === null;
	},

	isNumber : function(o) {
		return typeof o === 'number' && isFinite(o);
	},

	isObject : function(o) {
		return (o && (typeof o === 'object' || this.isFunction(o))) || false;
	},

	isString : function(o) {
		return typeof o === 'string';
	},

	isUndefined : function(o) {
		return typeof o === 'undefined';
	},

	hasOwnProperty : function(o, prop) {
		if (Object.prototype.hasOwnProperty) {
			return o.hasOwnProperty(prop);
		}

		return !this.isUndefined(o[prop]) && So.constructor.prototype[prop] !== o[prop];
	},

	isArray : function(o) {
		if (o) {
			return this.isNumber(o.length) && !this.hasOwnProperty(o.length);
		}
		return false;
	},

	propertyRetrieval : function(id, name, callback, url) {
		if (!this.isEmpty(id) && !this.isEmpty(name) && this.isFunction(callback)) {
			var retrievalCallback = {
				success : function(oResponse) {
					callback(oResponse.responseText);
				},
				failure : function(oResponse) {
					callback('');
				}
			}
			var param = 'id=' + encodeURI(id) + '&name=' + encodeURI(name);
			var transaction = YAHOO.util.Connect.asyncRequest('GET', url + "&" + param, retrievalCallback);
		}
	},

	insertAfter : function(newNode, existingNode) {
		if (existingNode.nextSibling) {
			existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
		} else {
			existingNode.parentNode.appendChild(newNode);
		}
	},

	getControl : function(id) {
		var control = null;

		try {
			control = eval("SG.cal.search." + id);
		} catch (e) {
		}
		if (control)
			return control;

		try {
			control = eval("SG.cal.tree." + id);
		} catch (e) {
		}
		if (control)
			return control;

		try {
			control = eval("SG.cal.grid." + id);
		} catch (e) {
		}
		if (control)
			return control;

		try {
			control = eval("SG.cal.filter." + id);
		} catch (e) {
		}
		if (control)
			return control;

		try {
			control = eval("SG.cal.balloon." + id);
		} catch (e) {
		}
		if (control)
			return control;

		return control;
	},

	isResponseSuccess : function(oResults) {
		return oResults && (oResults.result == "success" || oResults.result == "submit_ok");
	},

	getResults : function(oResponse) {
		try {
			return YAHOO.lang.JSON.parse(oResponse.responseText);
		} catch (e) {
			SG.log.warn("Response cannot be evaluated to JavaScript object. Maybe not valid JSON.");
			return null;
		}
	},

	clone : function(o) {
		function clonedObject(o) {
			if (SG.cal.util.isArray(o) && !SG.cal.util.isString(o)) {
				var arr = [];
				for ( var j = 0; j < o.length; j++) {
					arr[j] = new clonedObject(o[j]);
				}
				return arr;
			}
			for (i in o) {
				if (typeof o[i] == 'object') {
					this[i] = new clonedObject(o[i]);
				} else {
					this[i] = o[i];
				}
			}
		}
		return new clonedObject(o);
	},

	appendParams : function(sUrl, params) {
		var delimiter = ((sUrl.indexOf('?') == -1) ? '?' : '&');
		for ( var param in params) {
			sUrl += delimiter + param + "=" + params[param];
			delimiter = "&";
		}
		return sUrl;
	},

	formatMessage : /* String */function(/* String */message /* , Object... */) {
		if (SG.cal.util.isEmpty(message)) {
			return "";
		}
		for ( var /* int */i = 1; i < arguments.length; i++) {
			message = message.replace(new RegExp("\\{" + (i - 1) + "\}", "g"), arguments[i]);
		}
		return message;
	},
	
	setQueryStringValue: function(url, key, value) {
		var expr = new RegExp("([?|&])" + key + "=.*?(&|$)", "i");
		var keyValueString = key + "=" + value;
		if (url.match(expr)) {
			return url.replace(expr, "$1" + keyValueString + "$2");
		}
		return url + (url.indexOf("?") == -1 ? "?" : "&") + keyValueString;
	},
	
	getQueryStringValue: function(url, key) {
		var expr = new RegExp("([?|&])" + key + "=.*?(&|$)", "i");
		if (url.match(expr)) {
			var value = url.substring(url.indexOf(key) + key.length + 1);
			var ampPos = value.indexOf("&");
			return ampPos == -1 ? value : value.substring(0, ampPos);
		}
		return null;
	}

};

SG.namespace("SG.cal.util.animation");

/**
 * @namespace SG.cal.util.animation
 * @method toggleAnimated
 * @description Animatated the specified div. usefull css-styles: .animatedDiv {
 *              overflow: hidden; white-space: nowrap; float: right; }
 */
SG.cal.util.animation = {
	open :true,
	elementWidth :null,
	siblingWidth :null,
	dimensionAlreadySet :false,

	toggleAnimated : function(id, siblingid, animatorId, animSpeed, remainder) {
		var element = document.getElementById(id);
		var sibling = document.getElementById(siblingid);

		if (!this.dimensionAlreadySet) {
			this.elementWidth = element.clientWidth;
			this.siblingWidth = sibling.clientWidth;
			this.dimensionAlreadySet = true;
		}
		if (this.open) {
			attributes = {
				width : {
					to :remainder
				}
			}
			attributesSibling = {
				width : {
					to :this.siblingWidth + this.elementWidth - remainder
				}
			}
			document.getElementById(animatorId).style.background = 'transparent url(' + WKS.common.contextPath + '/yui/assets/skins/sam/layout_sprite.png) no-repeat scroll -20px -160px';
		} else {
			attributes = {
				width : {
					to :this.elementWidth
				}
			}
			attributesSibling = {
				width : {
					to :this.siblingWidth
				}
			}
			document.getElementById(animatorId).style.background = 'transparent url(' + WKS.common.contextPath + '/yui/assets/skins/sam/layout_sprite.png) no-repeat scroll -20px -200px';
		}
		this.open = !this.open;

		anim = new YAHOO.util.Anim(id, attributes, animSpeed);
		animSibling = new YAHOO.util.Anim(siblingid, attributesSibling, animSpeed);
		anim.animate();
		animSibling.animate();
	}
};

SG.namespace("SG.util.async");

SG.util.async = {

	// constants for logging
	JSON_ERROR :"jsonError",
	JSON_WARN :"jsonWarn",
	JSON_INFO :"jsonInfo",
	JSON_DEBUG :"jsonDebug",

	get : function(sUrl, success, overrides) {
		return SG.util.async.defaultRequest("GET", sUrl, success, null, overrides);
	},

	post : function(sUrl, success, overrides, params, form) {
		if (form) {
			YAHOO.util.Connect.setForm(form);
		}
		return SG.util.async.defaultRequest("POST", sUrl, success, params, overrides);
	},

	fetch : function(el, sUrl, cfg, success, form, leaveHTML) {
		if (!leaveHTML) {
			YAHOO.util.Event.purgeElement(el);
			el.innerHTML = "";
		}
		var overrides = {
			argument : {
				config :cfg,
				element :el,
				fnSuccess :success
			}
		}
		if (cfg) {
			if(cfg.failure && SG.cal.util.isFunction(cfg.failure)) {
				overrides.failure = cfg.failure;
			}
			if(cfg.timeout) {
				overrides.timeout= cfg.timeout;
			}	
			if(cfg.cache) {
				overrides.cache= cfg.cache;
			}	
		}
		if (form) {
			YAHOO.util.Connect.setForm(form);
		}
		return SG.util.async.defaultRequest("POST", sUrl, this.fetchSuccess, null, overrides);
	},

	fetchWithJS : function(el, sUrl, cfg, uniqueRequest, leaveHTML) {
		SG.log.debug("fetchWithJS");
		config = {};
		if (cfg) {
			config = cfg;
		}
		config.evalRoutine = this.evalRoutine;
		if (uniqueRequest && uniqueRequest == true) {
			sUrl = this.addUniqueUrlParam(sUrl);
		}
		this.fetch(el, sUrl, config, null, null, leaveHTML);
	},

	defaultRequest : function(method, sUrl, success, params, overrides) {
		if (SG.cal.sessionTimer) {
			SG.cal.sessionTimer.reset();
		}
		var callback = new SG.util.async.DefaultCallback(success, overrides);
		return YAHOO.util.Connect.asyncRequest(method, sUrl, callback, params);
	},

	logErrors : function(messages) {
		if (SG.cal.util.isArray(messages)) {
			for ( var i = 0; i < messages.length; i++) {
				SG.log.error(messages[i]);
			}
		}
	},
	logWarnings : function(messages) {
		if (SG.cal.util.isArray(messages)) {
			for ( var i = 0; i < messages.length; i++) {
				SG.log.warn(messages[i]);
			}
		}
	},
	logInfos : function(messages) {
		if (SG.cal.util.isArray(messages)) {
			for ( var i = 0; i < messages.length; i++) {
				SG.log.info(messages[i]);
			}
		}
	},
	logDebugs : function(messages) {
		if (SG.cal.util.isArray(messages)) {
			for ( var i = 0; i < messages.length; i++) {
				SG.log.debug(messages[i]);
			}
		}
	},
	defaultFailure : function(oResponse) {
		var standardCallback = new SG.util.async.DefaultCallback();
		standardCallback.failure(oResponse);
	},
	defaultSuccess : function(oResponse) {
		var standardCallback = new SG.util.async.DefaultCallback();
		standardCallback.success(oResponse);
	},
	fetchSuccess : function(oResponse, arguments) {
		YAHOO.plugin.Dispatcher.process(arguments.element, oResponse.responseText, arguments.config);
		if (SG.cal.util.isFunction(arguments.fnSuccess)) {
			arguments.fnSuccess();
		}
	},

	evalRoutine : function(c, config) {
		var jslink = document.createElement("script");
		jslink.setAttribute("type", "text/javascript");
		jslink.text = c;
		document.body.appendChild(jslink);
	},
	/**
	 * adds a unique parameter (rnd) to the url (timestamp)
	 * 
	 * @return
	 */
	addUniqueUrlParam : function(url) {
		return url += ((url.indexOf('?') == -1) ? '?' : '&') + "rnd=" + new Date().valueOf().toString();
	}

};

SG.util.async.DefaultCallback = function(success, overrides) {
	this.init(success, overrides);
};

SG.util.async.DefaultCallback.prototype = {
	init : function(success, overrides) {
		if (!overrides || !overrides["success"]) {
			this.successMethod = success;
		}
		for ( var param in overrides) {
			this[param] = overrides[param];
		}
	},

	success : function(oResponse) {
		if (oResponse && oResponse.getResponseHeader && oResponse.getResponseHeader.Vary 
				&& oResponse.getResponseHeader.Vary == "loginPage") {
			this.handleSessionTimeoutDialog();
		}
		var oResults = SG.cal.util.getResults(oResponse);
		if (oResults) {
			if (SG.cal.util.isResponseSuccess(oResults)) {
				if (this.successMethod && SG.cal.util.isFunction(this.successMethod)) {
					this.successMethod.call(this, oResults, oResponse.argument, oResponse);
				}
			} else {
				this.error(oResults);
			}
			if (oResults[SG.util.async.JSON_ERROR]) {
				SG.util.async.logErrors(oResults[SG.util.async.JSON_ERROR]);
			}
			if (oResults[SG.util.async.JSON_WARN]) {
				SG.util.async.logWarnings(oResults[SG.util.async.JSON_WARN]);
			}
			if (oResults[SG.util.async.JSON_INFO]) {
				SG.util.async.logInfos(oResults[SG.util.async.JSON_INFO]);
			}
			if (oResults[SG.util.async.JSON_DEBUG]) {
				SG.util.async.logDebugs(oResults[SG.util.async.JSON_DEBUG]);
			}
		} else {
			if (this.successMethod && SG.cal.util.isFunction(this.successMethod)) {
				this.successMethod.call(this, oResponse, oResponse.argument);
			}
		}
	},

	successMethod :null,

	failure : function(oResponse) {
		SG.log.error("Asynchronous request not successful");
		throw "Asynchronous request not successful";
	},

	error : function(oResults) {
		SG.log.warn("Request successful but returned 'ERROR' as return value");
	},

	cache :false,

	timeout :10000,
	
	handleSessionTimeoutDialog: function() {
		var containerDiv = document.createElement("div");
		containerDiv.id = "sessionTimeoutContainer";
		document.body.appendChild(containerDiv);
		var handleOK = function() {
			if (SG.cal.sessionTimer) {
				SG.cal.sessionTimer.logout();
			} else {
				alert('Leider konnte keine Login-Seite erkannt werden.');
			}
		};
		var text = "Ihre Session ist leider abgelaufen. Klicken Sie OK um zurück zum Login zu gelangen.";
		var dialog = new YAHOO.widget.SimpleDialog("sessionTimeoutDialog", {
			width: "400px",
			fixedcenter: true,
			visible: true,
			draggable: false,
			text: text,
			icon: YAHOO.widget.SimpleDialog.ICON_INFO,
			constraintoviewport: true,
			modal: true,
			buttons: [ { text:"OK", handler:handleOK, isDefault:true } ]

		});
		dialog.setHeader("Session Timeout");
		dialog.render(containerDiv);
	}
};

if (!Array.prototype.contains) {
	Array.prototype.contains = function(obj) {
		var len = this.length;

		for ( var i = 0; i < len; i++) {
			if (this[i] === obj) {
				return true;
			}
		}

		return false;
	};
}

SG.cal.util.Chain = function() {
	this.running = false;
	this.constructor.superclass.constructor.call(this, arguments);
	this.q = [];
}

YAHOO.extend(SG.cal.util.Chain, YAHOO.util.Chain, {
	running :null,

	run : function() {
		this.running = true;
		var returnValue = this.constructor.superclass.run.call(this);
		if (returnValue.q.length == 0) {
			this.running = false;
		}
	},

	stop : function() {
		this.running = false;
		return this.constructor.superclass.stop.call(this);
	}
});

SG.namespace("SG.cal.constants");

SG.cal.constants.id = "~id";
SG.cal.constants.controlId = "controlId";

SG.namespace("SG.cal.constants.controls.dialog");
SG.cal.constants.controls.dialog.SUBMIT_OK = "submit_ok";
SG.cal.constants.controls.dialog.SUBMIT_CANCEL = "submit_cancel";

SG.namespace("SG.log", "SG.cal.logging.init");

SG.log = {
	logreader :null,

	info : function(message) {
		YAHOO.log(message, "info");
	},

	debug : function(message) {
		YAHOO.log(message, "debug");
	},

	warn : function(message) {
		YAHOO.log(message, "warn");
	},

	error : function(message) {
		YAHOO.log(message, "error");
	},

	time : function(message) {
		YAHOO.log(message, "time");
	}
}

SG.cal.logging.init = function(loggerId, config) {
	if (SG.cal.util.isNull(SG.log.logreader)) {
		if (config.browserConsoleEnabled) {
			YAHOO.widget.Logger.enableBrowserConsole();
		} else {
			SG.log.logreader = new YAHOO.widget.LogReader(loggerId, config);
			if (config.collapsed) {
				SG.log.logreader.collapse();
			}
		}
		YAHOO.widget.Logger.reset();
	}
}

SG.namespace("SG.cal.util.DateFormat");

/**
 * @class DateFormat
 * @method DateFormat
 * @author fwi
 * @param {String}
 *            pattern the format pattern which is applied see
 *            java.text.SimpleDateFormat; possilbe patterns yy(yy): year M(M):
 *            month d(d): day H(H): hour 0-23 h(h): hour 1-12 a: AM/PM m(m):
 *            minute
 * @description Convert date by pattern
 */
SG.cal.util.DateFormat = function(pattern) {
	this.pattern = pattern;
}

SG.cal.util.DateFormat.prototype = {
	pattern :null,
	convertedDate :new function() {
		this.year = null;
		this.month = null;
		this.day = null;
		this.hours = null;
		this.hours1_12 = null;
		this.minutes = null;
		this.seconds = null;
		this.ampm = null;
		this.withYear = false;
		this.withMonth = false;
		this.withDay = false;
		this.withHours = false;
		this.withHours1_12 = false;
		this.withAmpm = false;

	},
	AM :"AM",
	PM :"PM",
	AM_PM_PATTERN :"a",
	DAY_PATTERN :"d",
	MONTH_PATTERN :"M",
	YEAR_PATTERN :"y",
	HOUR_PATTERN :"H",
	HOUR_1_12_PATTERN :"h", // hour in format 1-12
	MINUTE_PATTERN :"m",
	SECOND_PATTERN :"s",
	MAX_OFFSET_FUTURE :20, // from simpledateformat

	/**
	 * formats the given Date object into a string
	 * 
	 * @author fwi
	 * @param {Date}
	 *            date
	 * @throws IllegalArgument
	 * 
	 */
	format : function(date) {
		if (!(date instanceof Date)) {
			throw "IllegalArgument";
		}
		var formatedDate = this.pattern;
		var yearStart = this.pattern.indexOf(this.YEAR_PATTERN);
		var yearStop = this.pattern.lastIndexOf(this.YEAR_PATTERN);
		var yearString = this.pattern.substring(yearStart, yearStop + 1);

		var monthStart = this.pattern.indexOf(this.MONTH_PATTERN);
		var monthEnd = this.pattern.lastIndexOf(this.MONTH_PATTERN);
		var monthString = this.pattern.substring(monthStart, monthEnd + 1);

		var dayStart = this.pattern.indexOf(this.DAY_PATTERN);
		var dayEnd = this.pattern.lastIndexOf(this.DAY_PATTERN);
		var dayString = this.pattern.substring(dayStart, dayEnd + 1);

		var hour1_12Start = this.pattern.indexOf(this.HOUR_1_12_PATTERN);
		var hour1_12End = this.pattern.lastIndexOf(this.HOUR_1_12_PATTERN);
		var hour1_12String = this.pattern.substring(hour1_12Start, hour1_12End + 1);

		var hourStart = this.pattern.indexOf(this.HOUR_PATTERN);
		var hourEnd = this.pattern.lastIndexOf(this.HOUR_PATTERN);
		var hourString = this.pattern.substring(hourStart, hourEnd + 1);

		var minuteStart = this.pattern.indexOf(this.MINUTE_PATTERN);
		var minuteEnd = this.pattern.lastIndexOf(this.MINUTE_PATTERN);
		var minuteString = this.pattern.substring(minuteStart, minuteEnd + 1);

		var secondStart = this.pattern.indexOf(this.SECOND_PATTERN);
		var secondEnd = this.pattern.lastIndexOf(this.SECOND_PATTERN);
		var secondString = this.pattern.substring(secondStart, secondEnd + 1);

		var ampmStart = this.pattern.indexOf(this.AM_PM_PATTERN);
		var ampmEnd = this.pattern.lastIndexOf(this.AM_PM_PATTERN);
		var ampmString = this.pattern.substring(ampmStart, ampmEnd + 1);

		if (yearStart !== -1) {
			if ((yearStop - yearStart + 1) == 4) {
				formatedDate = formatedDate.replace(yearString, date.getFullYear());
			} else {
				formatedDate = formatedDate.replace(yearString, new String(date.getFullYear()).substring(2));
			}
		}
		if (monthStart != -1) {
			var month = date.getMonth() + 1;
			if (monthString.length == 2 && String(month).length == 1) {
				month = "0" + month;
			}
			formatedDate = formatedDate.replace(monthString, month);
		}
		if (dayStart != -1) {
			var day = date.getDate();
			if (dayString.length == 2 && String(day).length == 1) {
				day = "0" + day;
			}
			formatedDate = formatedDate.replace(dayString, day);
		}
		if (hour1_12Start != -1) {
			var hour1_12 = date.getHours();
			if (hour1_12 == 0) {
				hour1_12 = 12;
			}
			if (hour1_12 > 12) {
				hour1_12 -= 12;
			}
			if (hour1_12String.length == 2 && String(hour1_12).length == 1) {
				hour1_12 = "0" + hour1_12;
			}
			formatedDate = formatedDate.replace(hour1_12String, hour1_12);
		}
		if (hourStart != -1) {
			var hour = date.getHours();
			if (hourString.length == 2 && String(hour).length == 1) {
				hour = "0" + hour;
			}
			formatedDate = formatedDate.replace(hourString, hour);
		}
		if (minuteStart != -1) {
			var minute = date.getMinutes();
			if (minuteString.length == 2 && String(minute).length == 1) {
				minute = "0" + minute;
			}
			formatedDate = formatedDate.replace(minuteString, minute);
		}
		if (secondStart != -1) {
			var second = date.getSeconds();
			if (secondString.length == 2 && String(second).length == 1) {
				second = "0" + second;
			}
			formatedDate = formatedDate.replace(secondString, second);
		}
		if (ampmStart != -1) {
			var ampm = this.AM;
			if (hour1_12Start != -1 && (date.getHours() == 0 || date.getHours() > 12)) {
				ampm = this.PM
			} else {
				ampm = date.getHours() < 12 ? this.AM : this.PM;
			}
			formatedDate = formatedDate.replace(ampmString, ampm);
		}
		return formatedDate;
	},
	/**
	 * parses the text an convert it into a date
	 * 
	 * @author fwi
	 * @param {String}
	 *            text
	 * @throws ParseException
	 * @return the created Date
	 * @type Date
	 */
	parse : function(text) {
		var patternPos = 0;
		var offset = 0;
		var patternLength = this.pattern.length;
		var valuePos = 0;
		var value = "";
		var singleSymbol = false;
		var d = new Date();

		if (!text || text == "") {
			SG.log.debug("parseError: empty value");
			throw "ParseError";
		}

		for (patternPos = 0; patternPos < patternLength; patternPos++) {
			var ch = this.pattern.charAt(patternPos);
			if (this._isPatternSymbol(ch)) {
				value = "";
				var symbolLength = 1;
				var tmpIndex = patternPos;
				while (++tmpIndex < patternLength && this.pattern.charAt(tmpIndex) == ch) {
					symbolLength++;
				}
				if (ch == "a") {
					// special case for AM/PM
					value = text.substring(valuePos, valuePos + 2);
					value = value.toUpperCase();
					valuePos++;
				} else if (symbolLength == 1 && !isNaN(text.charAt(valuePos + 1))) {
					value = text.substring(valuePos, valuePos + 2);
					valuePos++;
				} else {
					value = text.substring(valuePos, valuePos + symbolLength);
					valuePos += (symbolLength - 1);
				}
				patternPos += (symbolLength - 1);
				try {
					this._setValue(ch, value);
				} catch (e) {
					throw "ParseError";
				}

			}
			valuePos++;
		}
		if (this._checkValue() == 0) {
			SG.log.debug("parseError");
			throw "ParseError";
		}
		SG.log.debug(YAHOO.lang.dump(this.convertedDate));
		d.setYear(this.convertedDate.year);
		d.setMonth(this.convertedDate.month - 1);
		d.setDate(this.convertedDate.day);
		d.setHours(this.convertedDate.hours);
		d.setMinutes(this.convertedDate.minutes);
		d.setSeconds(this.convertedDate.seconds);
		SG.log.debug(d);
		return new Date(this.convertedDate.year, this.convertedDate.month - 1, this.convertedDate.day,
				this.convertedDate.hours, this.convertedDate.minutes, this.convertedDate.seconds);
	},
	_isPatternSymbol : function(symbol) {
		var symbols = "ayMdHhms";
		return symbols.indexOf(symbol) != -1;
	},
	_setValue : function(symbol, value) {
		switch (symbol) {
		case this.YEAR_PATTERN:
			this.convertedDate.year = value;
			this.convertedDate.withYear = true;
			break;
		case this.MONTH_PATTERN:
			this.convertedDate.month = value;
			this.convertedDate.withMonth = true;
			break;
		case this.DAY_PATTERN:
			this.convertedDate.day = value;
			this.convertedDate.withDay = true;
			break;
		case this.HOUR_PATTERN:
			this.convertedDate.hours = value;
			this.convertedDate.withHour = true;
			break;
		case this.MINUTE_PATTERN:
			this.convertedDate.minutes = value;
			this.convertedDate.withMinute = true;
			break;
		case this.SECOND_PATTERN:
			this.convertedDate.seconds = value;
			this.convertedDate.withSecond = true;
			break;
		case this.HOUR_1_12_PATTERN:
			this.convertedDate.hours1_12 = value
			this.convertedDate.withHours1_12 = true;
			;
			break;
		case this.AM_PM_PATTERN:
			this.convertedDate.ampm = value
			this.convertedDate.withAmpm = true;
			;
			break;
		default:
			throw "InvalidArgument";
			break;
		}

	},
	_checkValue : function() {
		// check the year
		if (this.convertedDate.withYear && (isNaN(this.convertedDate.year) || this.convertedDate.year < 1)) {
			return 0;
		}
		// check month
		if (this.convertedDate.withMonth
				&& (isNaN(this.convertedDate.month) || this.convertedDate.month < 1 || this.convertedDate.month > 12)) {
			return 0;
		}
		// check the day
		if (this.convertedDate.withDay) {
			if (isNaN(this.convertedDate.day) || this.convertedDate.day < 1 || this.convertedDate.day > 31) {
				return 0;
			}
			if (this.convertedDate.month == 2) {
				if (((this.convertedDate.year % 4 == 0) && (this.convertedDate.year % 100 != 0))
						|| (this.convertedDate.year % 400 == 0)) {
					if (this.convertedDate.day > 29) {
						return 0;
					}
				} else {
					if (this.convertedDate.day > 28) {
						return 0;
					}
				}
			}
			if ((this.convertedDate.month == 4 || this.convertedDate.month == 6 || this.convertedDate.month == 9 || this.convertedDate.month == 11)
					&& this.convertedDate.day > 30) {
				return 0;
			}
		}
		// check hours
		if (this.convertedDate.withHour) {
			if (isNaN(this.convertedDate.hours) || this.convertedDate.hours < 0 || this.convertedDate.hours > 23) {
				return 0;
			}
		}

		if (this.convertedDate.withHours1_12) {
			if (this.convertedDate.withAmpm) {
				if (isNaN(this.convertedDate.hours1_12) || this.convertedDate.hours1_12 < 1
						|| this.convertedDate.hours1_12 > 12) {
					return 0;
				} else {
					if (this.convertedDate.ampm == this.PM) {
						if (this.convertedDate.hours1_12 == 12) {
							this.convertedDate.hours = 12; // 12 pm is noon
						} else {
							this.convertedDate.hours = 12 + parseInt(this.convertedDate.hours1_12);
						}
					} else {
						if (this.convertedDate.hours1_12 == 12) {
							this.convertedDate.hours = 0; // 12 am is midnight
						} else {
							this.convertedDate.hours = this.convertedDate.hours1_12;
						}
					}
				}
			} else {
				return 0;
			}
		}
		if (this.convertedDate.withMinute) {
			if (isNaN(this.convertedDate.minutes) || this.convertedDate.minutes < 0 || this.convertedDate.minutes > 59) {
				return 0;
			}
		}
		return 1;
	}
}
