
$(document).ready(function() {
	
	/**
	 * hModal - model window
	 * Usage: var modal = new $.hModal({
	 * 		title : 'Modal window title',
	 * 		content : '<p>Hello world</p>' 		
	 * });
	 */
	$.hModal = function(options) {
	
		this.title				= "Window";
		this.content 			= null;
		this.overlay			= true;
		this.overlay_opacity		= 50;
		this.autoshow			= true;
		this.beforeShow			= function() {};
		this.afterShow			= function() {};
		this.beforeClose		= function() {};
		this.afterClose			= function() {};

		this.$modal_wrapper				= null;
		this.$modal_content				= null;
		this.$modal_title				= null;
		
		$.extend(this, options);
		
		if (!this.title || this.title == "") this.title = "&nbsp;";
		
		this.drawModal();
		this.fill();
		this.center();
		if (this.autoshow) {
			this.show();
		}
		
	};
	$.hModal.prototype.drawModal = function() {
		
		var self = this;
		
		html  = '';
		html += '<div class="hModal_wrapper" style="display:none;">';
		html += '</div>';
		this.$modal_wrapper = $(html);
		
		html  = '';
		html += '<div class="hModal_title"><div class="hModal_close_btn"><a href="#"><img src="/img/modal_close_16x16.png" border="0" style="width:16px; height:16px;" /></a></div></div>';
		this.$modal_title = $(html);
		
		$(this.$modal_title)
			.find("a")
			.click(function(e) {
				if (e.button != 0) return false;
				e.preventDefault();
				self.close();
			});
		
		$(this.$modal_title).prependTo(this.$modal_wrapper);
		
		html  = '';
		html += '<div class="hModal_content"></a></div>';
		this.$modal_content = $(html);
		
		$(this.$modal_content).appendTo(this.$modal_wrapper);
				
	};
	$.hModal.prototype.fill = function() {
		$(this.$modal_title).append(this.title);
		$(this.$modal_content).append(this.content);
	};
	$.hModal.prototype.close = function() {
		this.beforeClose();
		$(this.$modal_wrapper).remove();
		if (this.overlay) $.hOverlay.hide();
		this.afterClose();
	};
	$.hModal.prototype.show = function() {
		this.beforeShow();
		if (this.overlay) $.hOverlay.show(this.overlay_opacity);
		$(this.$modal_wrapper).prependTo("body").show();
		this.afterShow();
	};
	$.hModal.prototype.center = function() {
		var self = this;
		//HACK: Initially, $modal_wrapper have 0 with and 0 height
		//So, we should recalculate width and height before center, see http://stackoverflow.com/questions/1997887/recalculate-element-height-in-jquery-after-class-change
		setTimeout(function() {
			$(self.$modal_wrapper)
				.css("position", "absolute")
				.css("z-index", 9999999)
				.css("top", ( $(window).height() - $(self.$modal_wrapper).height() ) / 2+$(window).scrollTop() + "px")
				.css("left", ( $(window).width() - $(self.$modal_wrapper).width() ) / 2+$(window).scrollLeft() + "px");
		}, 0);
		$(window).resize(function() {
			self.center();
		});
	};

	/**
	 * Dependant selects
	 * Usage: $.dependentSelects({
	 *     master : "#master_select",
	 *     slave  : "#slave_select",
	 *     url    : "index.php?q=#master_val#
	 * });
	 */
	$.dependentSelects = function(options) {
		
		this.master 			= null; 				//master selector
		this.slave				= null; 				//slave selector
		this.url				= null; 				//index.php?query=%%master_value%%
		this.master_value_var 	= "#master_val#";
		this.master_value 		= null;
		this.cache				= new Array();
		this.data				= {};
		this.autoclick			= false;
		$.extend(this, options);
		
		this.$master			= $(this.master);
		this.$slave				= $(this.slave);

		if (this.autoclick) {
			this.requestData();
		}
		
		this.bind();
	
	}
	$.dependentSelects.prototype.bind = function() {
		var self = this;
		$(this.$master).live("change", function(e) {
			self.requestData();
		});
	}
	$.dependentSelects.prototype.writeCache = function(key, value) {
		this.cache[key] = value;
		return true;
	}
	$.dependentSelects.prototype.readCache = function(key) {
		if (this.cache[key] != undefined) return this.cache[key];
		return false;
	}
	$.dependentSelects.prototype.getUrl = function() {
		v = $(this.$master).find("option:selected").val();
		return this.url.replace(this.master_value_var, v);
	}
	$.dependentSelects.prototype.beforeRequest = function() {		
		$(this.$master).attr("disabled", "disabled");
		$(this.$slave).attr("disabled", "disabled").html("");
	}
	$.dependentSelects.prototype.afterRequest = function() {
		$(this.$master).removeAttr("disabled");
		$(this.$slave).removeAttr("disabled");
	}
	$.dependentSelects.prototype.requestData = function() {
		this.beforeRequest();
		var self = this;
		$.ajax({
			type 	: 'post',
			data    : self.data,
			url 	: self.getUrl(),
			success : function(data) {
				if (data.status == "ok" && data.options != undefined) {
					options = '';
					$.each(data.options, function(val, name) {
						options += '<option value="'+val+'">'+name+'</option>';						
					});
					self.$slave.html(options);
					//console.log(data.selected);
					$.each(data.selected, function(val, name) {
						self.$slave.find('option[value="'+name+'"]').attr("selected", "selected");
					});					
				}
				self.afterRequest();
			},
			error 	: function() {
				self.afterRequest();
			},
			dataType: 'json'
		});
	}
	
	/**
	 * Sorting select
	 * Usage: $("#select").sortOptions();
	 */
	$.fn.sortSelectOptions = function() {
		var arr_options = [];
		var $options = $(this).find("option");
		for (var i = 0; i < $options.length; i++)  {
			arr_options[i] = [];
			arr_options[i][0] = $($options[i]).val();
			arr_options[i][1] = $($options[i]).html();
			arr_options[i][2] = $($options[i]).attr("selected");
		}
		arr_options.sort(function(i, ii) {
			a = i[1].toUpperCase();
			b = ii[1].toUpperCase();
			if (a > b) {
				return 1;
			} else if (a < b) {
				return -1;
			} else {
				return 0;
			}
		});
		for (var i = 0; i < $options.length; i++)  {
			$($options[i]).val(arr_options[i][0]);
			$($options[i]).html(arr_options[i][1]);
			if (arr_options[i][2] == "selected") {
				$($options[i]).attr("selected", "selected")
			} else {
				$($options[i]).removeAttr("selected");
			}
		}
	}
	
	/**
	 * Available/assigned selects
	 * Usage:
	 * new $.hAASelects({
	 *	    '$available_sel'   : $("#unassigned"),
	 *	    '$assigned_sel'    : $("#assigned"),
	 *	    '$assign_btn'      : $("#assign_btn"),
	 *	    '$unassign_btn'    : $("#unassign_btn"),
	 *	    '$assign_all_btn'  : $("#assign_all_btn"), //optional
	 *	    '$unassign_all_btn'  : $("#unassign_all_btn"), //optional
	 *	    '$reset_btn'       : $("#reset_form") //optional
	 *	}); 
	 */
	$.hAASelects = function(options) {
		
		this.$available_sel 	= null;
		this.$assigned_sel		= null;
		this.$assign_btn		= null;
		this.$unassign_btn		= null;
		this.$assign_all_btn	= null;
		this.$unassign_all_btn 	= null;
		this.$reset_btn			= null;
		this.null_available_sel = null; //data of select saved for reset purposes
		this.null_assigned_sel  = null; //data of select saved for reset purposes
		
		$.extend(this, options);
		
		this.null_available_sel = this.$available_sel.html();
		this.null_assigned_sel	= this.$assigned_sel.html();
		
		this.bind();
		
	}
	$.hAASelects.prototype.bind = function() {
		this.bindAssign();
		this.bindUnassign();
		if (this.$assign_all_btn != null && this.$assign_all_btn.length > 0)
			this.bindAssignAll();
		if (this.$unassign_all_btn != null && this.$unassign_all_btn.length > 0)
			this.bindUnassignAll();
		if (this.$reset_btn != null && this.$reset_btn.length > 0)
			this.bindReset();		
	}
	$.hAASelects.prototype.bindAssign = function() {		
		var self = this;
		this.$assign_btn.live("click", function(e) {
			e.preventDefault();
			self.$available_sel.find("option:selected").each(function() {
				self.$assigned_sel.append(this);
			});			
		});		
	}
	$.hAASelects.prototype.bindAssignAll = function() {		
		var self = this;
		this.$assign_all_btn.live("click", function(e) {
			e.preventDefault();
			self.$available_sel.find("option").each(function() {
				self.$assigned_sel.append(this);
			});			
		});		
	}	
	$.hAASelects.prototype.bindUnassign = function() {
		var self = this;
		this.$unassign_btn.live("click", function(e) {
			e.preventDefault();
			self.$assigned_sel.find("option:selected").each(function() {
				self.$available_sel.append(this);
			});
		});
	}
	$.hAASelects.prototype.bindUnassignAll = function() {
		var self = this;
		this.$unassign_all_btn.live("click", function(e) {
			e.preventDefault();
			self.$assigned_sel.find("option").each(function() {
				self.$available_sel.append(this);
			});
		});
	}
	$.hAASelects.prototype.bindReset = function() {
		var self = this;
		this.$reset_btn.live("click", function(e) {
			e.preventDefault();
			self.$assigned_sel.html(self.null_assigned_sel);
			self.$available_sel.html(self.null_available_sel);
		});
	}
		
	/**
	 * Check/unceck all checkboxes
	 * Usage: new $.hCheckboxes({selector : "input#main_checkbox", selected : ".chkbx"}); //selector is checkbox 
	 * 
	 * @param options object
	 */
	$.hCheckboxes = function(options) {
		
		this.selector 		= null; //jQuery selector for main "checkbox"
		this.selected 		= null; //jQuery selector for selecting checkboxes
		this.separate_any_and_all_callbacks = false; //Separate onAnyChecked and onAllChecked callbacks 
		
		this.onAllChecked	= function() {};
		this.onAnyChecked	= function() {};
		this.onNoChecked	= function() {};
		
		$.extend(this, options);				
		
		this.$selector		= $(this.selector);
		this.$selected		= $(this.selected);
		
		//binding actions
		this.bindSelectorAction();
		this.bindSelectedAction();
				
	}
	$.hCheckboxes.prototype.callback = function() {
		if (this.areAllChecked()) {			
			if (!this.separate_any_and_all_callbacks) {
				this.onAnyChecked();
			} else {
				this.onAllChecked();	
			}
		} else {
			if (this.isAnyChecked()) {
				this.onAnyChecked();
			} else {
				this.onNoChecked();
			}
		}
	}
	$.hCheckboxes.prototype.bindSelectorAction = function() {
		var self = this;
		this.$selector.live("click", function(e) {
			if (self.areAllChecked()) {
				self.changeAllState("uncheck");
				self.unmarkSelector();				
			} else {
				self.changeAllState("check");
				self.markSelector();								
			}
			self.callback();
		});
	}
	$.hCheckboxes.prototype.bindSelectedAction = function() {
		var self = this;
		this.$selected.live("click", function(e) {
			if ($(this).attr("checked") == "checked") {
				//unmarking
				self.unmarkSelector();
			} else {
				//marking
				if (self.areAllChecked()) {
					self.markSelector();
				} else {
					self.unmarkSelector();
				}
			}
			self.callback();
		});
	}
	$.hCheckboxes.prototype.isSelectorMarked = function() {
		if (this.$selector.is(":checked")) return true;
		return false;
		return true;
	}
	$.hCheckboxes.prototype.markSelector = function() {
		this.$selector.attr("checked", "checked");
		return true;return true
	}
	$.hCheckboxes.prototype.unmarkSelector = function() {
		this.$selector.removeAttr("checked");
		return true;
	}
	$.hCheckboxes.prototype.isAnyChecked = function() {
		var c = false;
		$(this.$selected).each(function($i) {
			if ($(this).is(":checked")) c = true;
		});
		return c;
	}
	$.hCheckboxes.prototype.areAllChecked = function() {
		var c = true;
		$(this.$selected).each(function($i) {
			if (!$(this).is(":checked")) {
				c = false;
			}
		});
		return c;
	}
	$.hCheckboxes.prototype.changeAllState = function(status) {
		//status = check / uncheck
		var status = status;
		$(this.$selected).each(function($i) {
			if (status == "check") {
				$(this).attr("checked", "checked");
			} else {
				$(this).removeAttr("checked");
			}
		});
	}
	
	/**
	 * Overlay div singleton object
	 * Usage: $.hOverlay.show(50); $.hOverlay.hide(); 
	 */
	$.hOverlay = {
		container_id : 'hOverlay',
		opacity : 10,
		drawContainer : function(opacity) {
			moz_opacity = this.opacity / 100;
			ie_opacity 	= this.opacity;
			html 		= '<div id="'+this.container_id+'" style="display:block; background-color:#000; position: absolute; left: 0px; top: 0px; width:100%; height:100%; text-align:center; z-index: 1000; filter:alpha(opacity='+ie_opacity+'); -moz-opacity:'+moz_opacity+'; -khtml-opacity: '+moz_opacity+'; opacity: '+moz_opacity+';"></div>';
			return html;
		},			
		show : function(opacity) {
			//Opacity in ie style (ie. 25%)
			if (opacity != undefined) {
				this.opacity = opacity;
			}			
			if ($("#"+this.container_id).length > 0) return true; //If already created overlay is found
			$body = $("body");		
			$body.prepend(this.drawContainer());
			return true;
		},
		hide : function() {
			$overlay = $("#"+this.container_id);
			if ($overlay.length > 0) {
				$overlay.remove();
			}
			return true;
		}
	};
	
	/**
	 * Corner messanger singleton object
	 * Usage: $.hCMsg.loader("I'm loader"); $.hCMsg.hide();
	 * Usage: $.hCMsg.error("I'm error"); $.hCMsg.hide();
	 * Usage: $.hCMsg.success("I'm success"); $.hCMsg.hide(); 
	 */
	$.hCMsg = {				
		wrapper_id : 'hCMsg_wrapper',
		message_id : 'hCMsg_message',					
		drawContainer : function(subject, message) {
			add_class = "hCMsg_"+subject;
			html = '';
			html += '<div id="'+this.wrapper_id+'" class="hCMsg_wrapper '+add_class+'">';
			html += '<div id="'+this.message_id+'">'+message+'</div>';
			html += '</div>';
			return html;
		},		
		isDisplayed : function() {
			if ($("#"+this.wrapper_id).length > 0) {
				return true;
			} else {
				return false;
			}
		},		
		display : function(html) {
			if (this.isDisplayed()) this.hide();
			$("body").prepend(html);
			this.bindDismiss();
			var self = this;
			setTimeout(
					function() {
						self.hide();
					}, 
					5000
			);
		},		
		bindDismiss : function() {
			var self = this;
			$("#"+this.wrapper_id).live("click", function() {
				self.hide();
			});
		},
		loader : function(message) {
			if (message == undefined) message = "Please wait...";
			this.display( this.drawContainer('loader', message) );			
		},
		success : function(message) {
			if (message == undefined) message = "Success!";
			this.display( this.drawContainer('success', message) );
		},
		error : function(message) {
			if (message == undefined) message = "Oops! Something goes wrong...";
			this.display( this.drawContainer('error', message) );			
		},
		hide : function() {
			if (this.isDisplayed()) {
				$("#"+this.wrapper_id).remove();
			}
		}
	}

});
