/*
 * jQuery UI PAF_Permission 0.1
 *
 * http://docs.jquery.com/UI/Selectables
 *
 * Depends:
 *	ui.core.js
 */
(function($) {

$.widget("ui.PAF_PermissionTable", $.extend({}, $.ui.mouse, {

	_init: function() {
		var self = this;

		 var currentDate = new Date();
		
		this.random = currentDate.getTime() + '_' + parseInt(Math.random() * 1000000);

		this.element.addClass("ui-selectable");

		this.dragged = false;

		// cache selectee children based on filter
		var selectees;
		this.refresh = function() {
			selectees = $(self.options.filter, self.element[0]);
			selectees.each(function() {
				var $this = $(this);
				var pos = $this.offset();
				var vValue = (self.options.useHiddenFields) ? $('input:hidden',this).val() : 2;
				$.data(this, "selectable-item", {
					element: this,
					$element: $this,
					left: pos.left,
					top: pos.top,
					right: pos.left + $this.width(),
					bottom: pos.top + $this.height(),
					startselected: false,
					selected: $this.hasClass('ui-selected'),
					selecting: $this.hasClass('ui-selecting'),
					unselecting: $this.hasClass('ui-unselecting'),
					value: vValue
				});
				
				
				var vSelectClass = 'ui-selectee';
				
				if (vValue == 2){
					vSelectClass = 'ui-selectee';
				} else if (vValue == 1){
					vSelectClass = 'ui-selectee-granted';
				} else if (vValue == 0){
					vSelectClass = 'ui-selectee-revoked';
				} else if (vValue == 3){
					vSelectClass = 'ui-selecting';
				}
				
				$this.removeClass('ui-selecting').removeClass('ui-selectee-granted').removeClass('ui-selectee-revoked').addClass(vSelectClass);
				$this.click(function(event){
					$(this).addClass('ui-selecting');
					self.markSelected(event);
				});
			});
		};

		this.refresh();

		this.selectees = selectees.addClass("ui-selectee");
		
		if (self.options.columnSelectors != null){
			self.options.columnSelectors.dblclick(function(event){
				var MyClassName = '.' + $(this).attr('id');
				self.selectees.filter(MyClassName).addClass('ui-selecting');
				self.markSelected(event);
			});
		}
		
		if (self.options.rowSelectors != null){
			self.options.rowSelectors.dblclick(function(event){
				var MyClassName = '.' + $(this).attr('id');
				self.selectees.filter(MyClassName).addClass('ui-selecting');
				self.markSelected(event);
			});
		}
		
		this.refreshSelector = function(){
			if (self.options.selectorTypeItem != null){
				self.selector = $(self.options.selectorTypeItem + ':checked').val();
			}
		}
		
		if (self.options.selectorTypeItem != null){
			this.selector = $(self.options.selectorTypeItem + ':checked').val();
			$(self.options.selectorTypeItem).change(function(){
				self.refreshSelector();
			});
		}
		
		this.refreshSelectionValue = function(){
			if (self.options.selectorValueItem != null){
				self.options.selectionValue = $(self.options.selectorValueItem + ':checked').val();
			}
		}
		
		this.refreshSelectionValue();
		
		if (self.options.selectorValueItem != null){
			if ($(self.options.selectorValueItem)[0].type == 'radio'){
				$(self.options.selectorValueItem).change(function(){ self.refreshSelectionValue() });
			}
		}
		
		

		this._mouseInit();

		this.helper = $(document.createElement('div'))
			.css({border:'1px dotted black'})
			.addClass("ui-selectable-helper");
		
		this.buildAskMeContainer();
	},
	
	buildAskMeContainer: function(){
		var self = this;
	
		var vRadioButton_Granted = $('<input type="radio" name="ask_me_radio_' + this.random + '" checked="checked" />').addClass('ask_me_radio').val(1);
		var vRadioButton_Revoked = $('<input type="radio" name="ask_me_radio_' + this.random + '" />').addClass('ask_me_radio').val(0);
		var vRadioButton_Undecided = $('<input type="radio" name="ask_me_radio_' + this.random + '" />').addClass('ask_me_radio').val(2);
		
		var vOKButton = $(document.createElement('input')).attr('type', 'button').val('OK').addClass('ask_me_radio');
		
		vOKButton.click(function(){
			var vOldValue = self.options.selectionValue;
			self.options.selectionValue = $('input:radio:checked',self.AskMe).val();;
			self.markSelected();
			self.options.selectionValue = vOldValue;
			$(self.AskMe).remove();
			self.buildAskMeContainer();
		});
		
		var Div_1 = $(document.createElement('div')).addClass('ask_me_div');
		var Div_2 = $(document.createElement('div')).addClass('ask_me_div');
		var Div_3 = $(document.createElement('div')).addClass('ask_me_div');
		var Div_4 = $(document.createElement('div')).addClass('ask_me_div');
		
		Div_1.append(vRadioButton_Granted).append("Granted");
		Div_2.append(vRadioButton_Revoked).append("Revoked");
		Div_3.append(vRadioButton_Undecided).append("Undecided");
		Div_4.append(vOKButton);
		
		this.AskMe = $(document.createElement('div'))
			.css({border:'1px solid black'})
			.addClass("ui-selectable-ask-me").append(Div_1).append(Div_2).append(Div_3).append(Div_4);
		
	},

	destroy: function() {
		this.element
			.removeClass("ui-selectable ui-selectable-disabled")
			.removeData("selectable")
			.unbind(".selectable");
		this._mouseDestroy();
	},

	_mouseStart: function(event) {
		var self = this;

		this.opos = [event.pageX, event.pageY];

		if (this.options.disabled)
			return;

		var options = this.options;

		this.selectees = $(options.filter, this.element[0]);

		// selectable START callback
		this.element.triggerHandler("selectablestart", [event, {
			"selectable": this.element[0],
			"options": options
		}], options.start);
		
		if (this.selector == 0){
			$('body').append(this.helper);
			// position helper (lasso)
			this.helper.css({
				"z-index": 100,
				"position": "absolute",
				"left": event.clientX,
				"top": event.clientY,
				"width": 0,
				"height": 0
			});
		}
		
		if (options.autoRefresh) {
			this.refresh();
		}

		this.selectees.filter('.ui-selected').each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.startselected = true;
			if (!event.metaKey) {
				selectee.$element.removeClass('ui-selected');
				selectee.selected = false;
				selectee.$element.addClass('ui-unselecting');
				selectee.unselecting = true;
				// selectable UNSELECTING callback
				self.element.triggerHandler("selectableunselecting", [event, {
					selectable: self.element[0],
					unselecting: selectee.element,
					options: options
				}], options.unselecting);
			}
		});

		var isSelectee = false;
		$(event.target).parents().andSelf().each(function() {
			if($.data(this, "selectable-item")) isSelectee = true;
		});
		return this.options.keyboard ? !isSelectee : true;
	},

	_mouseDrag: function(event) {
		var self = this;
		this.dragged = true;

		if (this.options.disabled)
			return;

		var options = this.options;

		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
		
		if (this.selector == 0){
			this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
		
			this.selectees.each(function() {
				var selectee = $.data(this, "selectable-item");
				//prevent helper from being selected if appendTo: selectable
				if (!selectee || selectee.element == self.element[0])
					return;
				var hit = false;
				if (options.tolerance == 'touch') {
					hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
				} else if (options.tolerance == 'fit') {
					hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
				}
	
				if (hit) {
					// SELECT
					if (selectee.selected) {
						selectee.$element.removeClass('ui-selected');
						selectee.selected = false;
					}
					if (selectee.unselecting) {
						selectee.$element.removeClass('ui-unselecting');
						selectee.unselecting = false;
					}
					if (!selectee.selecting) {
						selectee.$element.addClass('ui-selecting');
						selectee.selecting = true;
						// selectable SELECTING callback
						self.element.triggerHandler("selectableselecting", [event, {
							selectable: self.element[0],
							selecting: selectee.element,
							options: options
						}], options.selecting);
					}
				} else {
					// UNSELECT
					if (selectee.selecting) {
						if (event.metaKey && selectee.startselected) {
							selectee.$element.removeClass('ui-selecting');
							selectee.selecting = false;
							selectee.$element.addClass('ui-selected');
							selectee.selected = true;
						} else {
							selectee.$element.removeClass('ui-selecting');
							selectee.selecting = false;
							if (selectee.startselected) {
								selectee.$element.addClass('ui-unselecting');
								selectee.unselecting = true;
							}
							// selectable UNSELECTING callback
							self.element.triggerHandler("selectableunselecting", [event, {
								selectable: self.element[0],
								unselecting: selectee.element,
								options: options
							}], options.unselecting);
						}
					}
					if (selectee.selected) {
						if (!event.metaKey && !selectee.startselected) {
							selectee.$element.removeClass('ui-selected');
							selectee.selected = false;
	
							selectee.$element.addClass('ui-unselecting');
							selectee.unselecting = true;
							// selectable UNSELECTING callback
							self.element.triggerHandler("selectableunselecting", [event, {
								selectable: self.element[0],
								unselecting: selectee.element,
								options: options
							}], options.unselecting);
						}
					}
				}
			});
		} else {
			var X = event.pageX;
			var Y = event.pageY;
			
			
		
			this.selectees.each(function(aIndex, aElement){
				var vElement = $.data(this, "selectable-item");
				
				if (!vElement || vElement.element == self.element[0]){
					return;
				}
				
				var hit = false;
				hit = (vElement.left < X && vElement.right > X && vElement.top < Y && vElement.bottom > Y);
				
				if (hit){
					vElement.$element.addClass('ui-selecting');
					vElement.selecting = true;
					self.element.triggerHandler("selectableselecting", [event, {
						selectable: self.element[0],
						selecting: vElement.element,
						options: options
					}], options.selecting);
				}
			
			});
		}

		return false;
	},

	_mouseStop: function(event) {
		this.dragged = false;
		
		this.markSelected(event);
		
		this.helper.remove();

		return false;
	},
	
	markSelected: function(event){
		var self = this;
	
		var options = this.options;
		var vSelectClass = 'ui-selected';
		
		if (options.selectionValue == 2){
			vSelectClass = 'ui-selectee';
		} else if (options.selectionValue == 1){
			vSelectClass = 'ui-selectee-granted';
		} else if (options.selectionValue == 0){
			vSelectClass = 'ui-selectee-revoked';
		} else if (options.selectionValue == 3){
			vSelectClass = 'ui-selecting';
		}
		
		$('.ui-unselecting', this.element[0]).each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.$element.removeClass('ui-unselecting');
			selectee.unselecting = false;
			selectee.startselected = false;
			self.element.triggerHandler("selectableunselected", [event, {
				selectable: self.element[0],
				unselected: selectee.element,
				options: options
			}], options.unselected);
		});
		
		if (options.selectionValue == 3){
			var X = event.pageX;
			var Y = event.pageY;
			this.displayAskMe(X,Y);
		}

		$('.ui-selecting', this.element[0]).each(function() {
			var selectee = $.data(this, "selectable-item");
			if (selectee != undefined){
				selectee.$element.removeClass('ui-selecting').removeClass('ui-selectee-granted').removeClass('ui-selectee-revoked').addClass(vSelectClass);
				if (self.options.useHiddenFields && self.options.selectionValue != 3){
					$('input:hidden', $(this)).val(self.options.selectionValue);
				}
				selectee.selecting = false;
				selectee.selected = true;
				selectee.startselected = true;
				self.element.triggerHandler("selectableselected", [event, {
					selectable: self.element[0],
					selected: selectee.element,
					options: options
				}], options.selected);
			}
		});

		this.element.triggerHandler("selectablestop", [event, {
			selectable: self.element[0],
			options: this.options
		}], this.options.stop);
	},
	
	displayAskMe: function(X,Y){
		$('body').append(this.AskMe);
		this.AskMe.css({
				"z-index": 999,
				"position": "absolute",
				"left": X,
				"top": Y
			});
		
	}

}));

$.extend($.ui.PAF_PermissionTable, {
	version: "1.6",
	defaults: {
		appendTo: 'body',
		autoRefresh: true,
		cancel: ":input",
		delay: 0,
		distance: 1,
		filter: '*',
		tolerance: 'touch',
		selectorTypeItem: null,
		selectorValueItem: null,
		selectionValue: 1,
		useHiddenFields: true,
		columnSelectors: null,
		rowSelectors: null
	}
});

})(jQuery);
