if(jQuery) (function($){
	$.extend($.fn, {
		violetGrid : function (o) {
			if( !o ) var o = {};
			if( o.data == undefined ) o.data = null;
			if( o.draggable == undefined ) o.draggable = false;
			if( o.manager ==  undefined) o.manager = null;
			
			var oContainer = this;
			var documentBoundEvent = false;
			var posTopArray = [];
			var posLeftArray = [];
			var self = this;
			
			var createNode = function (node) {
				if( !node ) var node = {};
				if( node.item == undefined ) node.item = null; //item.id, item.name, item.parentID
				if( node.isDirectory == undefined ) node.isDirectory = false;
				if( node.showContextMenu == undefined ) node.showContextMenu = true;
				
				var icon = (node.item.minetype != undefined) ? 'icon-' + node.item.minetype: 'icon-directory';
				var type = (node.item.minetype != undefined) ? node.item.minetype: 'directory';
				var div = $('<div></div>',{'class':icon});
				
				var inputID = $('<input />',{'class':'id', type:'hidden',value:node.item.id});
				var inputName = $('<input />',{'class':'name',type:'hidden',value:node.item.name});
				var inputParent = $('<input />',{'class':'parentID',type:'hidden',value:node.item.parentID});
				var inputType = $('<input />',{'class':'type',type:'hidden',value:type});				
				
				var a = $('<a></a>',{id: node.item.id,href: '#',rel: node.item.name,text: node.item.name});
				var divLink = $('<div></div>',{'class':'file-name'}).append(a,inputID,inputName,inputParent,inputType);
				var li = $('<li></li>',{'class':'vscell',id:type+node.item.id}).append(div, divLink);
				
				bindNodeEvents(li);
				
				return li;
			}
			
			var bindNodeEvents = function (node) {
				var disabledItemsList = null;
				var menuName = '';
				
				var type = $(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="type"]').val();
				
				$(node)
					.bind("click", function (e){nodeClick(this,e);return false;})
					.bind("dblclick", function (e){nodeDblClick(this,e);return false;})
			}
			
			var nodeClick = function (node, event) {
				if (event.ctrlKey) {
					if (!isHightLight(node))
						hightlightNode(node);
					else
						clearHightLightNode(node);
				}
				else if (event.shiftKey) {
					var firstItem = $(oContainer).find('LI.selected');
					var aryNode = $(oContainer).find('> UL > LI');
					var start = aryNode.index(firstItem);
					var finish = aryNode.index(node);
					aryNode.slice(Math.min(start, finish), Math.max(start, finish) + 1).each( function (i,o){hightlightNode(o);});
				}
				else {
					clearAllHightLightNode(node);
					hightlightNode(node);
				}
			}
			
			var nodeDblClick = function (node) {
				var nodeObj = {id:$(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="id"]').val(),
							name: $(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="name"]').val(),
							parentID: $(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="parentID"]').val(),
							minetype: $(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="type"]').val()};
				
				o.manager.gridNodeDblClick(nodeObj);				
			}
			
			var hightlightNode = function (node) {
				$(node).addClass('selected');
			}
			
			var isHightLight = function (node) {
				return $(node).hasClass('selected');
			}
			
			var clearAllHightLightNode = function () {
				$(oContainer).find('> UL > LI').removeClass('selected');
			}
			
			var clearHightLightNode = function (node) {
				$(node).removeClass('selected');
			}
			
			var hightLightAllNode = function () {
				clearAllHightLightNode();
				$(oContainer).find('> UL > LI').addClass('selected');
			}
			
			var getAllHightLightNode = function () {
				return $(oContainer).find('> UL > LI.selected');
			}
			
			var initGrid = function () {
				$(oContainer).attr('unselectable','on')
				     .css({'-moz-user-select':'-moz-none',
				           '-moz-user-select':'none',
				           '-o-user-select':'none',
				           '-khtml-user-select':'none',
				           '-webkit-user-select':'none',
				           '-ms-user-select':'none',
				           'user-select':'none'
				     }).bind('selectstart', function(){ return false; 
				     }).bind('click', function(e){clearAllHightLightNode(); return false; });

				var ul = $('<ul></ul>',{'class':'vsgrid'});
				
				var parentDirID = o.manager.getTreeCurrentNode();
				if (o.data.DIRECTORIES.length > 0) {
					for (var d in o.data.DIRECTORIES) {
						if (o.data.DIRECTORIES[d].parentID == parentDirID) {
							var li = createNode ({item: o.data.DIRECTORIES[d]});
							$(ul).append(li);
						}
					}
				}
				
				if (o.data.FILES.length > 0) {
					for (var f in o.data.FILES) {
						if (o.data.FILES[f].parentID == parentDirID) {
							var li = createNode ({item: o.data.FILES[f]});
							$(ul).append(li);
						}
					}
				}
				
				$(oContainer).find ('UL').remove();
				$(oContainer).append(ul);
			}

			var destroyNode = function (node) {
				var nodeID = $(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="id"]').val();
				var nodeType = $(node).find('> DIV[class^="file-name"] > INPUT[type="hidden"][class^="type"]').val();
				$(node).remove();
			}

			/******************
			 * RENAME - START *
			 ******************/
			var renameInit = function (node) {				
				var editor = $('<input />',{'class':'rename', type: 'text', value:$(node).text()});
				$(editor).bind('focusout', function(e){renameCancel(node)});
				$(editor).bind('keydown', function(e){
						var keycode = (e.keyCode ? e.keyCode : e.which);
						if (keycode == '27') {
							renameCancel(node);
						}else if(keycode == '13') renameComplete(node);
						e.stopPropagation();
					});
				
				$(node).text('');
				$(node).append(editor);
				$(editor).focus();
				$(editor).select();
			}
			
			var renameCancel = function (node) {
				var nodeID = $(node).parent().find('> INPUT[type="hidden"][class^="id"]').val();
				var nodeType = $(node).parent().find('> INPUT[type="hidden"][class^="type"]').val();
				var nodeName = $(node).parent().find('> INPUT[type="hidden"][class^="name"]').val();
				var nodeParent = $(node).parent().find('> INPUT[type="hidden"][class^="parentID"]').val();
				var itemIndex =  o.manager.searchItemByID(nodeID, nodeType == 'directory' ? nodeType:'file');

				$(node).find('>INPUT').remove();
				$(node).text(nodeName);
				$(node).select();
			}
			
			var renameComplete = function (node) {
				var editor = $(node).find('>INPUT');
				var dirID = $(node).attr('id');
				var newName = $(editor).val();
				$(node).attr('rel', newName);
				$(node).text(newName);
				$(node).find('>INPUT').remove();

				/*treeNodes[dirID].name = newName;
				updateData(dirID, 'rename');*/
			}
			/******************
			 * RENAME - END *
			 ******************/
			
			this.reloadGrid = function () {
				initGrid();
			}
			
			this.setData = function (data) {
				o.data = data;
			}
			
			this.rename = function (item) {
				/*console.log('rename');
				console.log(item);*/
			}
			
			this.createNode = function (node) {
				var node = createNode ({item: node});
				$(oContainer).find ('UL').append(node);
			}
			
			this.deletion = function (id, type) {
				destroyNode($(oContainer).find('LI#'+type+id));
			}

			this.rename = function (key) {
				var hightlightedNodes = self.getHightLightItem();
				if ($(hightlightedNodes).length == 0 || $(hightlightedNodes).length > 1) return false;

				var nodeID = $(hightlightedNodes).get(0).id;
				var nodeType = $(hightlightedNodes).get(0).type;

				var selectedNode = $(oContainer).find('LI#' + nodeType + nodeID + '.vscell > DIV.file-name > A#' + nodeID);
				if (key == 113) {
					renameInit(selectedNode);
				}
				else if (key == 27) {
					renameCancel(selectedNode);
				}

				return true;
			}			
			
			this.getHightLightItem = function () {
				var nodeSelected = $(oContainer).find('LI.vscell.selected');				
				var items = [];
				
				if ($(nodeSelected).length > 0) {
					$(nodeSelected).each (function(i,o) {
							var item = {
								id: $(this).find('> DIV.file-name > INPUT[type="hidden"][class^="id"]').val(),
								name: $(this).find('> DIV.file-name > INPUT[type="hidden"][class^="name"]').val(),
								parentID: $(this).find('> DIV.file-name > INPUT[type="hidden"][class^="parentID"]').val(),
								type: $(this).find('> DIV.file-name > INPUT[type="hidden"][class^="type"]').val()
							};
							items.push(item);
						});
				}
				
				return items;
			}

			this.selectAllNode = function () {
				hightLightAllNode();
			}
			
			this.initialize = function () {
				initGrid();
				return this;
			};
			
			return this.initialize();
		}
	});
})(jQuery);