/**
 * @requires JABB 0.1
 */
function EBCal () {
	
	var document = window.document;
	
	this.options = {};
	this.date = null;
	this.event_id = null;
	this.category_id = null;
	this.version = "0.1";
	this.getVersion = function () {
		return this.version;
	};

	this.bindCalendar = function () {
		var i, len, self = this,
			cells = JABB.Utils.getElementsByClass(this.options.class_name_dates, document.getElementById(this.options.container_calendar), "td");
		//Add "click" event to calendar cells
		for (i = 0, len = cells.length; i < len; i++) {
			JABB.Utils.addEvent(cells[i], "click", function (event) {
				self.triggerLoading('message_1', self.options.container_events);
				if (self.options.position === 2) {
					document.getElementById(self.options.container_calendar).style.display = 'none';
				}
				self.loadEvents(this.getAttributeNode("axis").value);
			});
		}
		//Add "click" event to calendar nav links
		var a = JABB.Utils.getElementsByClass(self.options.class_name_month, document.getElementById(self.options.container_calendar), "a");
		for (var m, y, rel, j = 0, alen  = a.length; j < alen; j++) {
			JABB.Utils.addEvent(a[j], "click", function () {
				rel = this.getAttributeNode("rel").value;
				switch (rel.split("-")[0]) {
				case 'next':
					m = parseInt(self.options.month, 10) + parseInt(self.options.view, 10) > 12 ? parseInt(self.options.month) + parseInt(self.options.view, 10) - 12 : parseInt(self.options.month) + parseInt(self.options.view, 10);
					y = parseInt(self.options.month, 10) + parseInt(self.options.view, 10) > 12 ? parseInt(self.options.year) + 1 : parseInt(self.options.year);
					break;
				case 'prev':
					m = parseInt(self.options.month, 10) - parseInt(self.options.view, 10) < 1 ? parseInt(self.options.month) - parseInt(self.options.view, 10) + 12 : parseInt(self.options.month) - parseInt(self.options.view, 10);
					y = parseInt(self.options.month, 10) - parseInt(self.options.view, 10) < 1 ? parseInt(self.options.year) - 1 : parseInt(self.options.year);
					break;
				}
				self.triggerLoading('message_5', self.options.container_calendar);
				self.loadCalendar(m, y);
			});
		}
		
		// Add 'mouseover' and 'mouseout' event
		var t = JABB.Utils.getElementsByClass('calendarEvent', document.getElementById(this.options.container_calendar), "td");
		for (i = 0, len = t.length; i < len; i++) {
			JABB.Utils.addEvent(t[i], "mouseover", function (event) {
				if (document.getElementById('t_' + this.getAttributeNode("id").value)) {
					document.getElementById('t_' + this.getAttributeNode("id").value).style.visibility = 'visible';
				}
			});
			JABB.Utils.addEvent(t[i], "mouseout", function (event) {
				if (document.getElementById('t_' + this.getAttributeNode("id").value)) {
					document.getElementById('t_' + this.getAttributeNode("id").value).style.visibility = 'hidden';
				}
			});
		}
	};
	
	this.bindEvents = function () {
		var i, len, self = this,
			btn = JABB.Utils.getElementsByClass(this.options.class_name_events, document.getElementById(this.options.container_events), "input");			
		// Add "click" event to Book button
		for (i = 0, len = btn.length; i < len; i++) {
			JABB.Utils.addEvent(btn[i], "click", function (event) {
				self.triggerLoading('message_2', self.options.container_events);
				self.loadBookingForm(this.getAttributeNode("rev").value);
			});
		}
	};
	
	this.bindClose = function () {
		var i, len, self = this,
		btnClose = JABB.Utils.getElementsByClass(this.options.events_close, document.getElementById(this.options.container_events), "a");
		// Add "click" event to Close link
		for (i = 0, len = btnClose.length; i < len; i++) {
			JABB.Utils.addEvent(btnClose[i], "click", function (event) {
				if (event.preventDefault) {
					event.preventDefault();
				}
				document.getElementById(self.options.container_events).innerHTML = "";
				if (self.options.position === 2) {
					document.getElementById(self.options.container_calendar).style.display = "";
				}				
				return false;
			});
		}
	};
	
	this.bindBookingForm = function () {
		var self = this;
		// Add "change" event to Payment method combo box
		if (document.forms[self.options.booking_form_name] && document.forms[self.options.booking_form_name][self.options.booking_form_payment_method]) {
			JABB.Utils.addEvent(document.forms[self.options.booking_form_name][self.options.booking_form_payment_method], "change", function () {
				// if there will be any credit card option...
				if (self.options.cc_data_flag) {
					var $ccData = JABB.Utils.getElementsByClass(self.options.cc_data_wrapper, document.forms[self.options.booking_form_name], "DIV")[0],
						$value = this.options[this.selectedIndex].value;
					
					if ($value == 'creditcard') {
						// show the credit cards fields
						$ccData.style.display = "block";
						
						// for each field add a requered class name
						for (i = 0; i < self.options.cc_data_names.length; i++) {
							JABB.Utils.addClass(document.forms[self.options.booking_form_name][self.options.cc_data_names[i]], 'EBCal_Required');
						}
					} else {
						// hide the credit cards fields
						$ccData.style.display = "none";
						
						// for each field remove the requered class name
						for (i = 0; i < self.options.cc_data_names.length; i++) {
							JABB.Utils.removeClass(document.forms[self.options.booking_form_name][self.options.cc_data_names[i]], 'EBCal_Required');
						}
					}
				}
			});
		}
		
		//Add "click" event to Submit button
		if (document.forms[self.options.booking_form_name] && document.forms[self.options.booking_form_name][self.options.booking_form_submit_name]) {
			JABB.Utils.addEvent(document.forms[self.options.booking_form_name][self.options.booking_form_submit_name], "click", function (event) {
				var $this = this;
				$this.disabled = true;
				if (!self.validateBookingForm($this)) {
					return;
				}
				if ($this.form.captcha) {
					JABB.Ajax.getJSON(self.options.get_booking_captcha_url + "&captcha=" + $this.form.captcha.value, function (json) {
						switch (json.code) {
						case 100:
							self.errorHandler('\n' + self.options.validation.error_captcha);
							$this.disabled = false;
							break;
						case 200:
							self.loadBookingSummary(JABB.Utils.serialize(document.forms[self.options.booking_form_name]));
							self.triggerLoading('message_4', self.options.container_events);							
							break;
						}
					});
				} else {
					self.loadBookingSummary(JABB.Utils.serialize(document.forms[self.options.booking_form_name]));
					self.triggerLoading('message_4', self.options.container_events);					
				}				
			});
		}
		//Add "click" event to Cancel button
		if (document.forms[self.options.booking_form_name] && document.forms[self.options.booking_form_name][self.options.booking_form_cancel_name]) {
			JABB.Utils.addEvent(document.forms[self.options.booking_form_name][self.options.booking_form_cancel_name], "click", function (event) {
				this.disabled = true;
				self.triggerLoading('message_1', self.options.container_events);
				self.loadEvents();				
			});
		}
		// Add "change" event to price
		var priceSelect = JABB.Utils.getElementsByClass(self.options.class_name_price, document.forms[self.options.booking_form_name], "SELECT");
		if (document.forms[self.options.booking_form_name]) {
			for (var i = 0, len = priceSelect.length; i < len; i++) {
				JABB.Utils.addEvent(priceSelect[i], "change", function (event) {
					self.loadPrices();
				});
			}
		}
	};
	
	this.bindBookingSummary = function (post) {
		var self = this;
		//Add "click" event to Submit button
		if (document.forms[self.options.booking_summary_name] && document.forms[self.options.booking_summary_name][self.options.booking_summary_submit_name]) {
			JABB.Utils.addEvent(document.forms[self.options.booking_summary_name][self.options.booking_summary_submit_name], "click", function (event) {
				var $this = this;
				$this.disabled = true;
				if (!self.validateBookingSummary($this)) {
					return;
				}
				JABB.Ajax.postJSON(self.options.get_booking_save_url + "&cid=" + self.options.calendar_id, function (json) {
					switch (json.code) {
					case 100:
						self.errorHandler('\n' + self.options.message_8);
						$this.disabled = false;
						break;
					case 200:
						self.loadPaymentForm(json);
						break;
					}																								
				}, post + "&" + JABB.Utils.serialize(document.forms[self.options.booking_summary_name]) + "&calendar_id=" + self.options.calendar_id + "&event_id=" + self.event_id);
			});
		}
		//Add "click" event to Cancel button
		if (document.forms[self.options.booking_summary_name] && document.forms[self.options.booking_summary_name][self.options.booking_summary_cancel_name]) {
			JABB.Utils.addEvent(document.forms[self.options.booking_summary_name][self.options.booking_summary_cancel_name], "click", function (event) {
				this.disabled = true;
				self.triggerLoading('message_2', self.options.container_events);
				self.loadBookingForm(undefined, post, 1);
			});
		}
	};
	
	this.bindCategory = function () {
		var self = this;
		if (document.forms[self.options.category_form_name] && document.forms[self.options.category_form_name].category_id) {
			JABB.Utils.addEvent(document.forms[self.options.category_form_name].category_id, "change", function (event) {
				self.category_id = this.options[this.selectedIndex].value;
				self.loadCalendar(self.options.month, self.options.year);
			});
		}
	};
	
	this.loadCalendar = function (m, y) {
		var self = this,
			queryStr = "&cid=" + self.options.calendar_id + "&view=" + self.options.view + "&month=" + m + "&year=" + y + "&category_id=" + self.category_id;
		JABB.Ajax.sendRequest(self.options.get_calendar_url + queryStr, function (req) {
			document.getElementById(self.options.container_calendar).innerHTML = req.responseText;
			document.getElementById(self.options.container_events).innerHTML = "";
			if (self.options.position === 2) {
				document.getElementById(self.options.container_calendar).style.display = '';
			}
			self.options.month = m;
			self.options.year = y;
			self.bindCalendar();
		});
	};
	
	this.loadEvents = function (date) {
		if (typeof date !== "undefined") {
			this.date = date;
		}
		var self = this,
			qs = "&cid=" + self.options.calendar_id + "&date=" + self.date + "&category_id=" + self.category_id;
		JABB.Ajax.sendRequest(this.options.get_events_url + qs, function (req) {
			document.getElementById(self.options.container_events).innerHTML = req.responseText;
			self.bindEvents();
			self.bindClose();
		});
	};
	
	this.loadPrices = function () {
		var self = this,
			arr = [],
			price_arr = JABB.Utils.getElementsByClass(self.options.class_name_price, document.forms[self.options.booking_form_name], "SELECT");
		for (var i = 0, len = price_arr.length; i < len; i++) {
			arr.push(price_arr[i].name + "=" + encodeURIComponent(price_arr[i].options[price_arr[i].selectedIndex].value));
		}
		JABB.Ajax.get(self.options.get_price_url + "&cid=" + self.options.calendar_id + "&" + arr.join("&"), self.options.container_price);
	};
	
	this.loadBookingForm = function (event_id, post, loadPrices) {
		if (typeof event_id !== "undefined") {
			this.event_id = event_id;
		}
		var self = this,
			qs = "&cid=" + self.options.calendar_id + "&date=" + self.date + "&event_id=" + self.event_id;
		JABB.Ajax.sendRequest(self.options.get_booking_form_url + qs, function (req) {
			document.getElementById(self.options.container_events).innerHTML = req.responseText;
			self.bindBookingForm();
			self.bindClose();
			if (typeof loadPrices !== "undefined") {
				self.loadPrices();
			}
		}, post);
	};
	
	this.loadBookingSummary = function (post) {
		var self = this,
			qs = "&cid=" + self.options.calendar_id;
		JABB.Ajax.sendRequest(self.options.get_booking_summary_url + qs, function (req) {
			document.getElementById(self.options.container_events).innerHTML = req.responseText;
			self.bindBookingSummary(post);
			self.bindClose();
		}, post);
	};
	
	this.loadPaymentForm = function (obj) {
		var self = this,
		qs = "&cid=" + self.options.calendar_id,
		bs, d;
		JABB.Ajax.sendRequest(self.options.get_payment_form_url + qs, function (req) {
			bs = document.forms[self.options.booking_summary_name];
			if (bs && bs.parentNode) {
				d = document.createElement("div");
				d.innerHTML = req.responseText;
				bs.parentNode.insertBefore(d, bs);
				
				if (typeof document.forms[self.options.payment[obj.payment]] != 'undefined') {
					document.forms[self.options.payment[obj.payment]].submit();
				} else {
					self.triggerLoading('message_7', self.options.container_events);
				}
			}
			
		}, "id=" + obj.booking_id);
	};
	
	this.toggleCreditCard = function () {
		
	};
	
	this.validateBookingForm = function (btn) {
		var re = /([0-9a-zA-Z\.\-\_]+)@([0-9a-zA-Z\.\-\_]+)\.([0-9a-zA-Z\.\-\_]+)/,
			message = "";
		
		var frm = document.forms[this.options.booking_form_name];
		for (var i = 0, len = frm.elements.length; i < len; i++) {
			var cls = frm.elements[i].getAttributeNode("class");
			if (cls && cls.value.indexOf("EBCal_Required") !== -1) {
				switch (frm.elements[i].nodeName) {
				case "INPUT":
					switch (frm.elements[i].type) {
					case "checkbox":
					case "radio":
						if (!frm.elements[i].checked && frm.elements[i].getAttribute("rev")) {
							message += "\n - " + frm.elements[i].getAttribute("rev"); 
						}
						break;
					default:
						if (frm.elements[i].value.length === 0 && frm.elements[i].getAttribute("rev")) {
							message += "\n - " + frm.elements[i].getAttribute("rev");
						}
						break;
					}
					break;
				case "TEXTAREA":
					if (frm.elements[i].value.length === 0 && frm.elements[i].getAttribute("rev")) {						
						message += "\n - " + frm.elements[i].getAttribute("rev");
					}
					break;
				case "SELECT":
					switch (frm.elements[i].type) {
					case 'select-one':
						if (frm.elements[i].value.length === 0 && frm.elements[i].getAttribute("rev")) {
							message += "\n - " + frm.elements[i].getAttribute("rev"); 
						}
						break;
					case 'select-multiple':
						var has = false;
						for (j = frm.elements[i].options.length - 1; j >= 0; j = j - 1) {
							if (frm.elements[i].options[j].selected) {
								has = true;
								break;
							}
						}
						if (!has && frm.elements[i].getAttribute("rev")) {
							message += "\n - " + frm.elements[i].getAttribute("rev");
						}
						break;
					}
					break;
				default:
					break;
				}
			}
			if (cls && cls.value.indexOf("EBCal_Email") !== -1) {
				if (frm.elements[i].nodeName === "INPUT" && frm.elements[i].value.length > 0 && frm.elements[i].value.match(re) == null) {
					message += "\n - " + this.options.validation.error_email;
				}
			}
		}
		var price_arr = JABB.Utils.getElementsByClass(this.options.class_name_price, document.forms[this.options.booking_form_name], "SELECT"),
			max = frm.event_max_people.value,
			cnt = 0;
		for (var i = 0, len = price_arr.length; i < len; i++) {
			cnt += parseInt(price_arr[i].options[price_arr[i].selectedIndex].value, 10);
		}
		if (cnt > max) {
			message += "\n - " + this.options.validation.error_max.replace(/\[max\]/, max);
		} else if (cnt === 0) {
			message += "\n - " + this.options.validation.error_min;
		}
		if (message.length === 0) {
			return true;
		} else {
			this.errorHandler(message);		
			btn.disabled = false;
			return false;
		}
	};
	
	this.validateBookingSummary = function (btn) {
		var po = document.getElementsByName("payment_option"),
			poLength = po.length,
			pass = false,
			message = "\n" + this.options.validation.error_payment,
			i;
			
		for (i = poLength - 1; i >= 0; i--) {
			if (po[i].checked) {
				pass = true;
				break;
			}
		}
		
		if (poLength === 0) {
			pass = true;
		}
		
		if (pass) {
			return true;
		} else {
			this.errorHandler(message);		
			btn.disabled = false;
			return false;
		}
	};

	this.errorHandler = function (message) {
		var err = JABB.Utils.getElementsByClass("EBCal_Error", document.forms[this.options.booking_form_name], "P");
		if (err[0]) {
			err[0].innerHTML = this.options.validation.error_title + message.replace(/\n/g, "<br />");
			err[0].style.display = '';
		} else {
			alert(this.options.validation.error_title + message);
		}
	};
	
	this.triggerLoading = function (message, container) {
		document.getElementById(container).innerHTML = this.options[message];
		document.getElementById(this.options.container_messages).innerHTML = '';
	};

	this.init = function (calObj) {
		this.options = calObj;
		this.bindCalendar();
		this.bindCategory();
	}
}
