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

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

	_init: function() {
		var self = this;

		this.element.addClass("treeview");
		if ($('a.selected',this.element).length == 1){
			this.chosen_item = $('a.selected',this.element).parent();
		}

		this.selected_element = null;
		this.drag_root_node_placeholer = null;
		this.insert_before_item = null;

		this.root_nodes = $('>li>span', this.element);

		this.root_nodes.addClass('root_nodes');

		this.refresh_expands = function(){
				$('li', this.element).each(function (aIndex, aElement){
					if ($('>ul>li',aElement).length == 0){
						$('>ul',aElement).remove();
					}

				});
				$('div.hitarea', this.element).remove();
				$('li', this.element).each(function(aIndex, aElement){
					$(this).removeClass('last');
					$(aElement).status = 'single';
					if (self.options.expandable){
						if ($(aElement).find('ul').length > 0){
							var vHitarea = $('<div></div>').addClass('hitarea');
							$(aElement).status = 'open';

							if ($(aElement).hasClass('closed')){
								//vHitarea.addClass('expandable-hitarea');
								$(aElement).find('ul:first').hide();
								$(aElement).status = 'closed';
								vHitarea.addClass('collapsable-hitarea');
							}

							vHitarea.click(function(){

								if ($(aElement).hasClass('closed')){
									$('ul',aElement).show();
									$(aElement).removeClass('closed');
								} else {
									$('ul',aElement).hide();
									$(aElement).addClass('closed');
								}

								self.refresh_expands();
							});


							$(aElement).prepend(vHitarea);


						}
					}

				});


				this.element.find("li").filter(':last-child:not(ul)').each(function(aIndex, aElement){
					if ($(this).find('ul').length > 0){
						if (self.options.expandable){
							$(this).addClass('last');

							if ($(this).hasClass('closed')){
								$('div.hitarea', this).removeClass('expandable-hitarea').removeClass('lastCollapsed').addClass('lastExpandable');
							} else {
								$('div.hitarea', this).removeClass('expandable-hitarea').removeClass('lastExpandable').addClass('lastCollapsed');
							}
						} else {
							$(this).addClass('last');
						}
					} else {
						$(this).addClass('last');
					}
				});

		}
		this.refresh_expands();

		var vElements = null;
		if (this.options.move_root_nodes){
			if (this.options.draggable_nodes_class){
				vElements = $('span.' + this.options.draggable_nodes_class, this.element);
			} else {
				vElements = $('span', this.element);
			}
		} else {
			if (this.options.draggable_nodes_class){
				vElements = $('span.' + this.options.draggable_nodes_class, this.element).filter(':not(.root_nodes)', this.element);
			} else {
				vElements = $('span', this.element).filter(':not(.root_nodes)', this.element);
			}
		}

		vElements.mousedown(function(){
					self.selected_element = this;
					self.createDragItem();
					self.refresh();
				});

		if (this.options.enable_select_items){
			$('span', this.element).click(function(){

				self.selectItem(this);

				if (self.dragItem != null){
					self.dragItem.remove();
					self.dragItem = null;
				}
			});
		}

		var selectees = null;
		this.drop_item = null;

		this.refresh = function() {
			if (self.options.sortable){
				selectees = $(self.options.draggable_items, this.element);

				selectees.filter(':not(span.not_selectable)').each(function(aIndex, aElement) {
					var $this = $(this);
					var pos = $this.offset();
					var vElement = aElement;
					var vStage = 0;
					var vSubStages = 0;




					$.data(this, "drop-item", {
						element: this,
						$element: $this,
						left: pos.left,
						top: pos.top,
						right: pos.left + $this.width(),
						bottom: pos.top + $this.height(),
						startselected: false
					});
				});

				this.selectees = selectees;
			}

			if (self.handleCheckboxOnclickEvent){
				$('input:checkbox',this.element).change(function(){
					alert('test');
				});
			}
		};

		this.refresh();



		this.element.find("li").filter(':last-child:not(ul)').each(function(aIndex, aElement){

			if ($(this).find('ul').length > 0){
				$(this).addClass('last');
				$('div.hitarea', this).removeClass('expandable-hitarea').addClass('lastExpandable');
			} else {
				$(this).addClass('last');
			}
		});



		if (self.options.sortable){
			this._mouseInit();
		}

	},


	destroy: function() {
		this.element
			.removeClass("ui-PAF_TreeView")
			.removeData("PAF_TreeView")
			.unbind(".PAF_TreeView");
		this._mouseDestroy();

	},

	getCurrentStage: function(aSpanElement){
		var vElement = aSpanElement;
		var vStage = 1;
		while(!$(vElement).parent().hasClass('treeview')){

			if ($(vElement).is('ul')){
				vStage = (vStage+1);
			}
			vElement = $(vElement).parent();
		}

		return vStage;
	},

	getSubstageCount: function(aElementLI){
		var self = this;
		var vTotalCounter = 0;
		var vCounter = 0;
		$('span', aElementLI).each(function(aIndex, aElement){
			vCounter = self.getCurrentStage(aElement)

			if (vCounter > vTotalCounter){
				vTotalCounter = vCounter;
			}
		});

		return vCounter;
	},

	createDragItem: function(){
		if (this.selected_element == null){
			return false;
		}

		this.dragItem = $(this.selected_element).clone();
		this.dragItem.addClass('not_selectable');
		this.dragItem.css('position', 'absolute');
		this.dragItem.css('z-index', '500');
		this.dragItem.css('background-color', 'white');
		this.dragItem.insertAfter($(this.selected_element).parent());
		this.dragItem.hide();
		//$(this.selected_element).parent().hide();
	},

	addRootItem: function(aName){

		if (aName == undefined){
			aName = {name: 'New Folder', type: 'normal', span_id: ''};
		}

		if (aName.name == undefined){
			aName.name = 'New Folder'
		}

		if (aName.type == undefined){
			aName.type = 'normal'
		}

		if (aName.span_id == undefined){
			aName.span_id = ''
		}

		var self = this;


			if (self.options.alphabetical_order){
				if (self.options.order_primary_class != null && self.options.order_primary_class == self.options.add_span_class){
					$('> li > span.' + self.options.order_primary_class, $(this.element)).each(function(aIndex, aElement){
						if (self.insert_before_item == null && aName.name < $('a', aElement).html()){
							self.insert_before_item = aElement;
						}
					});
				} else {
					$(' > li > span', $(this.element)).each(function(aIndex, aElement){
						if (self.insert_before_item == null && aName.name < $('a', aElement).html()){
							self.insert_before_item = aElement;
						}
					});
				}
			}

			var vNewItem = null;
			if (aName.type == 'checkbox'){
				vNewItem = $('<li class="last"><span id="' + aName.span_id + '" class="' + self.options.add_span_class + '">&nbsp;<input type="checkbox">&nbsp;<a href="JavaScript:void(0);">' + aName.name + '</a></span></li>');
			} else {
				vNewItem = $('<li class="last"><span id="' + aName.span_id + '" class="' + self.options.add_span_class + '"><a href="JavaScript:void(0);">' + aName.name + '</a></span></li>');
			}

			if (this.options.enable_select_items){
				$('span:first',vNewItem).click(function(){

					self.selectItem(this);
				});
			}

			$('span',vNewItem).mousedown(function(){
					self.selected_element = this;
					self.createDragItem();
				});

			if (this.insert_before_item != null){
				vNewItem.insertBefore($(this.insert_before_item).parent());
			} else {
				$(this.element).append(vNewItem);
			}

			this.refresh_expands();
			this.refresh();

			var event = jQuery.Event("added");
			event.type="added";
			this._trigger("added", event, vNewItem);

			if (this.options.enable_select_items){

				this.selectItem($('span',vNewItem));
			}

			this.insert_before_item = null;


	},

	addItem: function(aName){

		if (aName == undefined){
			aName = {name: 'New Folder', type: 'normal', span_id: ''};
		}

		if (aName.name == undefined){
			aName.name = 'New Folder'
		}

		if (aName.type == undefined){
			aName.type = 'normal'
		}

		if (aName.span_id == undefined){
			aName.span_id = ''
		}

		var self = this;

		if (this.options.no_selection_add_to_root && this.chosen_item == null){
			this.chosen_item = $('>li:first>span:first', this.element);
		}

		if (this.chosen_item != null){
			if (self.options.just_add_to_spans_with_class != null && !$(this.chosen_item).hasClass(self.options.just_add_to_spans_with_class)){
				return;
			}

			if (self.options.maximum_stages && self.getCurrentStage($(this.chosen_item)) >= self.options.maximum_stages){
				var event = jQuery.Event("droped_but_max_stages");
				event.type="droped_but_max_stages";
				this._trigger("droped_but_max_stages", event, (self.getCurrentStage($(this.chosen_item))+1));
				return;
			}

			if ($(this.chosen_item).parent().find('ul').length == 0){
				$(this.chosen_item).parent().append($('<ul>'));
			}

			if (self.options.alphabetical_order){
				if (self.options.order_primary_class != null && self.options.order_primary_class == self.options.add_span_class){
					$('> ul > li > span.' + self.options.order_primary_class, $(this.chosen_item).parent()).each(function(aIndex, aElement){
						if (self.insert_before_item == null && aName.name < $('a', aElement).html()){
							self.insert_before_item = aElement;
						}
					});
				} else {
					$('> ul > li > span', $(this.chosen_item).parent()).each(function(aIndex, aElement){
						if (self.insert_before_item == null && aName.name < $('a', aElement).html()){
							self.insert_before_item = aElement;
						}
					});
				}
			}

			var vNewItem = null;
			if (aName.type == 'checkbox'){
				vNewItem = $('<li class="last"><span id="' + aName.span_id + '" class="' + self.options.add_span_class + '"><input type="checkbox"><a href="JavaScript:void(0);">' + aName.name + '</a></span></li>');
			} else {
				vNewItem = $('<li class="last"><span id="' + aName.span_id + '" class="' + self.options.add_span_class + '"><a href="JavaScript:void(0);">' + aName.name + '</a></span></li>');
			}

			if (this.options.enable_select_items){
				$('span:first',vNewItem).click(function(){

					self.selectItem(this);
				});
			}

			$('span',vNewItem).mousedown(function(){
					self.selected_element = this;
					self.createDragItem();
				});

			if (this.insert_before_item != null){
				vNewItem.insertBefore($(this.insert_before_item).parent());
			} else {
				$(this.chosen_item).parent().find('ul:first').append(vNewItem);
			}

			this.refresh_expands();
			this.refresh();

			var event = jQuery.Event("added");
			event.type="added";
			this._trigger("added", event, vNewItem);

			if (this.options.enable_select_items){

				this.selectItem($('span',vNewItem));
			}

			this.insert_before_item = null;


		}
	},

	clearSelection: function(){
		if (this.chosen_item != null){
			$('>a',this.chosen_item).removeClass('selected');
		}
		this.chosen_item = null;
	},

	selectItem: function(aItem){

		$('a.selected',this.element).removeClass('selected');
		this.chosen_item = aItem;

		$('>a',this.chosen_item).addClass('selected');

		var event = jQuery.Event("selected");
		event.type="selected";
		this._trigger("selected", event, $(this.chosen_item));
	},

	renameItem: function(aOptions){
		if (this.chosen_item != null){
			if (aOptions.name == ''){
				aOptions.name = '&nbsp;';
			}

			$('>a',this.chosen_item).html(aOptions.name);
		}
	},

	removeItem: function(){
		var self = this;
		if (this.chosen_item != null){
			var vItem = $(this.chosen_item).parent();
			vItem.remove();

			this.chosen_item = null;

			this.refresh_expands();
			this.refresh();

			var event = jQuery.Event("removed");
			event.type="removed";
			this._trigger("removed", event, vItem);
		}
	},

	replaceItem: function(aHTML){
		var self = this;
		if (this.chosen_item != null){
			$(this.chosen_item).parent().replaceWith(aHTML);
			if ($('a.selected', $(this.element)).length > 0){
			   this.chosen_item = $('a.selected', $(this.element)).parent();

			}
			var vElements = null;
			if (this.options.move_root_nodes){
				vElements = $('span', this.element);
			} else {
				vElements = $('span', this.element).filter(':not(.root_nodes)', this.element);
			}

			vElements.mousedown(function(){
					self.selected_element = this;
					self.createDragItem();
			});

			if (this.options.enable_select_items){

				$('span', this.element).unbind('click').click(function(){

					self.selectItem(this);
					if (self.dragItem != null){
						self.dragItem.remove();
						self.dragItem = null;
					}
				});
			}

			this.refresh_expands();
			this.refresh();
		}
	},

	getStructure: function (aGivenElement){
		var self = this;
		var vStructureObject = new Object();

		var vElements = null;
		if (aGivenElement == undefined){
			vElements = $('>li',this.element);
		} else {
			vElements = $('>ul >li',aGivenElement);
		}

		vElements.each(function(aIndex, aElement){
			var vSubObject = new Object();
			vSubObject['element'] = $(aElement);

			if ($('>ul >li', aElement).length > 0){
				vSubObject['children'] = self.getStructure(aElement);
			}
			vStructureObject[aIndex] = vSubObject;
		});

		return vStructureObject;
	},

	_createRootNodePlaceHolder: function(){
		self = this;

		var vNewItem = $('<li class="root_placeholder"><span class="folder"><a href="JavaScript:void(0);">Drag here for Root Entry</a></span></li>');
		$('span:first',vNewItem).click(function(){

			self.selectItem(this);
		});

		$('span',vNewItem).mousedown(function(){
				self.selected_element = this;
				self.createDragItem();
			});

		this.drag_root_node_placeholer = vNewItem;

		$(this.element).prepend(vNewItem);
		this.refresh_expands();
		this.refresh();
	},

	_mouseCapture: function(event, overrideHandle) {

		return true;
	},

	_mouseStart: function(event, overrideHandle, noActivation) {

		return true;
	},

	_mouseDrag: function(event) {
		var self = this;
		var X = event.pageX;
		var Y = event.pageY;
		var vDropItem = null;
		if (this.dragItem == null){
			return false;
		}
		this.dragItem.show();

		if (self.options.dropon){
			if (this.options.droponroot && this.drag_root_node_placeholer == null){
				this._createRootNodePlaceHolder();
			}

			this.selectees.each(function(aIndex, aElement){
				var vElement = $.data(this, "drop-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){
					vDropItem = aElement;
					$(aElement).addClass('drop-item-hovered');
				} else {
					$(aElement).removeClass('drop-item-hovered');
				}

			});
			this.drop_item = vDropItem;
		} else {
			if (this.options.droponroot && this.drag_root_node_placeholer == null){
				this._createRootNodePlaceHolder();
			}

			$('.spacer', this.element).remove();
			$('.drop-item-hovered').removeClass('drop-item-hovered');
			this.refresh();
			this.refresh_expands();
			this.selectees.each(function(aIndex, aElement){
				var vElement = $.data(this, "drop-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){

					if (!$(aElement).hasClass('folder')){

						var vArea = vElement.top+($(aElement).height()/2);

						if(Y > vArea){
							$('<li class="spacer"><div></div></li>').insertAfter($(aElement).parent());
						} else {
							$('<li class="spacer"><div></div></li>').insertBefore($(aElement).parent());
						}
					} else {

						$(aElement).addClass('drop-item-hovered');

						vDropItem = aElement;
					}
				} else {

				}

			});
			this.drop_item = vDropItem;

		}

		if (this.dragItem != null){
			this.dragItem.css('left', event.pageX);
			this.dragItem.css('top', event.pageY);
		}
		return false;
	},

	_mouseStop: function(event, noPropagation) {
		var self = this;
		var vItemReordered = false;
		if (this.dragItem == null){
			return false;
		}

		this.dragItem.remove();
		this.dragItem = null;

		if (self.options.dropon){
			if (self.options.alphabetical_order){
					if (self.options.order_primary_class != null && $(this.selected_element).hasClass(self.options.order_primary_class)){
						$('> ul > li > span.' + self.options.order_primary_class, $(this.drop_item).parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					} else {
						$('> ul > li > span', $(this.drop_item).parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					}
				}


				$('span',$(this.selected_element).parent()).each(function(aIndex, aElement){
					if (aElement == self.drop_item){
						vDropOnChild = true;
					}
				});

				var vHolder = $(this.selected_element).parent().parent();

				if(this.drop_item != null && !vDropOnChild){
					var vStages = (this.getSubstageCount($(this.selected_element).parent())-this.getCurrentStage($(this.selected_element)))+this.getCurrentStage($(this.drop_item))+1;

					if ((this.options.maximum_stages == null || vStages <= this.options.maximum_stages)){
						if (this.insert_before_item != null){
							$(this.selected_element).parent().insertBefore($(this.insert_before_item).parent());
						} else {
							var vItem = null;

							if ($(this.drop_item).parent().find('> ul').length == 0){
								vItem = $(this.drop_item).parent().append($('<ul>'));
							}

							vItem = $(this.drop_item).parent().find('ul:first');

							if (self.options.alphabetical_order && self.options.order_primary_class != null && self.insert_before_item == null && $(this.selected_element).hasClass(self.options.order_primary_class) ){
								vItem.prepend($(this.selected_element).parent());
							} else {
								vItem.append($(this.selected_element).parent());
							}
							vItemReordered = true;
						}

						if (vHolder.find('li').length == 0){
							vHolder.remove();
						}
					} else {
						var vChildstages = self.getSubstageCount($(this.selected_element).parent())-self.getCurrentStage($(this.drop_item));
						var event = jQuery.Event("droped_but_max_stages");
						event.type="droped_but_max_stages";
						this._trigger("droped_but_max_stages", event, vStages);
					}
				}

		} else {
			var vDropOnChild = false;

			if (this.drag_root_node_placeholer != null && $(this.drop_item).parent().hasClass('root_placeholder')){
				if (self.options.alphabetical_order){
					if (self.options.order_primary_class != null && $(this.selected_element).hasClass(self.options.order_primary_class)){
						$('> ul > li > span.' + self.options.order_primary_class, this.element).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					} else {
						$('> ul > li > span', this.element.parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					}
				}

				if (self.insert_before_item != null){

					$(this.selected_element).parent().insertBefore($(self.insert_before_item));
				} else {
					this.element.append($(this.selected_element).parent());
				}
				vItemReordered = true;
			}else if (this.drop_item == null){
				if (self.options.alphabetical_order){
					if (self.options.order_primary_class != null && $(this.selected_element).hasClass(self.options.order_primary_class)){
						$(' > li > span.' + self.options.order_primary_class, $('.spacer', self.element).parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					} else {
						$(' > li > span', $('.spacer', self.element).parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('>a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					}
				}

				$('li',$(this.selected_element).parent()).each(function(aIndex, aElement){

					$('.spacer', self.element).each(function(aIndex2, aElement2){
						if (aElement == aElement2){
							vDropOnChild = true;
						}
					});

				});

				if (this.selected_element != null && !vDropOnChild && (this.options.maximum_stages == null || (self.getCurrentStage($('.spacer > div', this.element))+self.getSubstageCount($(this.selected_element).parent()) <= this.options.maximum_stages))){
					if (self.options.alphabetical_order && self.options.order_primary_class != null && self.insert_before_item == null && $(this.selected_element).hasClass(self.options.order_primary_class) ){
						$('.spacer', this.element).parent().prepend($(this.selected_element).parent());
						$('.spacer', this.element).remove();
					} else if (self.insert_before_item != null){
						$(this.selected_element).parent().insertBefore($(self.insert_before_item).parent());
						$('.spacer', this.element).remove();
					} else if(self.options.alphabetical_order){
						$('.spacer', this.element).parent().append($(this.selected_element).parent());
						$('.spacer', this.element).remove();
					} else {
						$('.spacer', this.element).replaceWith($(this.selected_element).parent());
					}

					vItemReordered = true;
				} else {
					$('.spacer', this.element).remove();
				}

			} else {
				if (self.options.alphabetical_order){
					if (self.options.order_primary_class != null && $(this.selected_element).hasClass(self.options.order_primary_class)){
						$('> ul > li > span.' + self.options.order_primary_class, $(this.drop_item).parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					} else {
						$('> ul > li > span', $(this.drop_item).parent()).each(function(aIndex, aElement){
							if (self.insert_before_item == null && $('a', self.selected_element).html() < $('a', aElement).html()){
								self.insert_before_item = aElement;
							}
						});
					}
				}


				$('span',$(this.selected_element).parent()).each(function(aIndex, aElement){
					if (aElement == self.drop_item){
						vDropOnChild = true;
					}
				});

				var vHolder = $(this.selected_element).parent().parent();

				if(this.drop_item != null && !vDropOnChild && (this.options.maximum_stages == null || (self.getCurrentStage($(this.drop_item))+1+self.getSubstageCount($(this.selected_element).parent()) <= this.options.maximum_stages))){
					if (this.insert_before_item != null){
						$(this.selected_element).parent().insertBefore($(this.insert_before_item).parent());
						vItemReordered = true;
					} else {
						var vItem = null;

						if ($(this.drop_item).parent().find('> ul').length == 0){
							vItem = $(this.drop_item).parent().append($('<ul>'));
						}

						vItem = $(this.drop_item).parent().find('ul:first');

						if (self.options.alphabetical_order && self.options.order_primary_class != null && self.insert_before_item == null && $(this.selected_element).hasClass(self.options.order_primary_class) ){
							vItem.prepend($(this.selected_element).parent());
						} else {
							vItem.append($(this.selected_element).parent());
						}

						vItemReordered = true;
					}

					if (vHolder.find('li').length == 0){
						vHolder.remove();
					}
				}
			}
		}
		var vSelectedItem = this.selected_element;
		this.selected_element = null;
		this.insert_before_item = null;

		if (this.drag_root_node_placeholer != null){
			this.drag_root_node_placeholer.remove();
			this.drag_root_node_placeholer = null;
		}

		this.refresh();
		this.refresh_expands();


		$('.drop-item-hovered').removeClass('drop-item-hovered');

		if (vItemReordered && $('>span:first',$(vSelectedItem).parent().parent().parent()) != undefined){
			var event = jQuery.Event("reordered");
			event.type="reordered";
			this._trigger("reordered", event, {'complete': this.getStructure(), 'item': $(vSelectedItem), 'parent':$('>span:first',$(vSelectedItem).parent().parent().parent())});
		}

		return true;
	}

}));

$.extend($.ui.PAF_TreeView, {
	getter: "serialize toArray",
	version: "1.7.2",
	eventPrefix: "sort",
	defaults: {
		distance: 1,
		move_root_nodes: false,
		sortable: false,
		expandable: false,
		droponroot: false,
		draggable_items: 'span',
		dropable_items: 'span',
		dropon: true,
		alphabetical_order: false,
		order_primary_class: null,
		enable_select_items: true,
		maximum_stages: null,
		add_span_class: 'folder',
		just_add_to_spans_with_class: null,
		no_selection_add_to_root: false,
		draggable_nodes_class: null,
		handleCheckboxOnclickEvent: true
	}
});

})(jQuery);
