if(jQuery) (function($){
	
	$.extend($.fn, {
		violetGrid: function (o) {
			if( !o ) var o = {};
			if( o.container == undefined ) o.container = $(this);
			if( o.defaultViewMode == undefined ) o.defaultViewMode = 'thumbnail';//or 'list'
			if( o.directoryTreeData == undefined ) o.directoryTreeData = null;
			if( o.dirIDprefix == undefined ) o.dirIDprefix = null;
			if( o.host == undefined ) o.host = 'http://localhost/';
			if( o.tree == undefined ) o.tree = null;
			
			if( o.sharemodal == undefined ) o.sharemodal = $("#box-shareto");
			if( o.copymodal == undefined ) o.copymodal = $("#box-copyto");
			if( o.movemodal == undefined ) o.movemodal = $("#box-moveto");
			
			var currentObj = {};
			
			var createNode = function (d) {
				if( !d ) var d = {};
				if( d.id == undefined ) d.id = null;
				if( d.name == undefined ) d.name = null;
				if( d.minetype == undefined ) d.minetype = 'directory';
				if( d.parentID == undefined ) d.parentID = null;
				if( d.clickEvent == undefined ) d.clickEvent = null;
				if( d.customEvent == undefined ) d.customEvent = null;

				var strHTML = '<div class="vscell '+ d.minetype +'" rel="id:' + d.id + '">';
					strHTML += '<div class="selector unselected">';
					strHTML += 	'<div class="icon-' + d.minetype + '"></div>';
					strHTML += '</div>';
					strHTML += '<div class="file-name unselected">' + d.name + '</div>';
					strHTML += '</div>';
				
				var disabledItemsList = null;
				var enabledItemsList = null;
				var menuName = '';
				
				if (d.minetype == 'directory') {
					disabledItemsList = ['preview'];
					menuName = 'gridMenuDir';
				}
				else {
					disabledItemsList = ['newfolder'];
					menuName = 'gridMenuFile';
				}
				
				$(o.container).append(strHTML);

				$('div[rel="id:'+ d.id +'"].' + d.minetype).bind('click',function(e){itemClick(this)});
				$('div[rel="id:'+ d.id +'"].' + d.minetype).bind('dblclick',function(e){doubleClick(this)});
				
				$('div[rel="id:'+ d.id +'"].' + d.minetype).draggable({ containment: "parent",helper: "original" });
				
				$('div[rel="id:'+ d.id +'"].' + d.minetype).contextMenu({
					menu: menuName,
					disabledItems: disabledItemsList,
					enabledItems: enabledItemsList
				}, function(action, el, pos) {
					itemClick(el);
					switch(action) {
						case 'newfolder':
							openNewFolderModal(currentObj);
							break;
						case 'rename':
							rename(el);
							break;
						case 'share':
							showShareModal(currentObj);
							break;
						case 'copy':
						case 'cut':
							showCopyModal(currentObj, action);
							break;
						default:
							break;
					}
				});
			}
			
			var openNewFolderModal = function (c) {
				$('#box-newfolder').modal('show');
				$('#frm-newfolder').find('#f-parentid').val(c.id);
			}
			
			var bindCreateFolder = function () {
				$('#box-newfolder').find('#frm-newfolder').unbind('submit');
				$('#box-newfolder').find('#btn-submit-newfolder').unbind('click');
				
				$('#box-newfolder').find('#frm-newfolder').bind('submit', 
					function(e){
						if ($('#frm-newfolder').find('#f-newfoldername').val() == '') {
							alert('Chưa nhập tên thư mục mới!');
						}else {
							var postData = $('#box-newfolder').find('#frm-newfolder').serializeArray();
							var script = 'ajax/privatecontent/createdir';
							sendCommand({
								script: script,
								postdata:postData,
								callbackSuccess: function (parsedData) {
													createNode({
														id: parsedData.id,
														name: parsedData.name,
														curentNode: currentObj,
														hidden: false,
														addToJSONData:true});
													o.tree.createDir(parsedData);
												}
							});
							
							$('#box-newfolder').modal('hide');
						}
						
						e.preventDefault();
				});
				
				$('#box-newfolder').on('show.bs.modal', function () {
					$('#box-newfolder').find('#frm-newfolder').get(0).reset();
				});
				
				$('#box-newfolder').on('shown.bs.modal', function () {
					$('#box-newfolder').find('#frm-newfolder').find('#f-newfoldername').focus();
				});
				
				$('#box-newfolder').find('#btn-submit-newfolder').bind('click',
					function (){
						$('#box-newfolder').find('#frm-newfolder').submit();
				});
			}
			
			var keyboardRename = function () {
				$(document).bind('keydown','keypress', function(e) {
					var selectedItem = $('.selector.selected').parent();
					
					switch( e.keyCode ) {
						case 113:
							rename(selectedItem);
							break;
						case 27:
							cancelRename(selectedItem);
							break;
						default:
							break;
					}
				});
			}
			
			var showShareModal = function (obj) {
				if (obj.type == undefined || obj.type == null) obj.type = 'directory';
				$(o.sharemodal).modal('show');
				$(o.sharemodal).find('INPUT#txtSelectedObj').val(obj.name);
				$(o.sharemodal).find('.modal-header').text('Chia sẻ ' + (obj.type == 'directory'?'thư mục ':'file ') + obj.name);
			}
			
			var showCopyModal = function (obj, action) {
				var modalTitle = action == 'copy' ? 'Sao chép ' + (obj.type == 'directory'?'thư mục ':'file ') + obj.name:'Di chuyển ' + (obj.type == 'directory'?'thư mục':'file') + ' ' + obj.name
				var submitTitle = action == 'copy' ? 'Sao chép' : 'Di chuyển';
				var submitIcon = action == 'copy' ? '<i class="icon-copy"></i>' : '<i class="icon-cut"></i>';
						
				//btn-primary
				$(o.copymodal).modal('show');
				$(o.copymodal).find('INPUT#txtSelectedObj').val(obj.name);
				$(o.copymodal).find('.modal-header').text(modalTitle);
				$(o.copymodal).find('.btn-primary').empty();
				$(o.copymodal).find('.btn-primary').append(submitIcon + "\n" + submitTitle);
				
				var selectTree = $(o.copymodal).find('#select-destination-tree').violetTree({
					container: $('#select-destination-tree'),
					expandEasing: 'easeOutBounce', 
					collapseEasing: 'easeOutBounce',
					homeDirNameDisplay: "Thư mục gốc",
					contextmenuON: false
				});
				
				$(o.copymodal).find('.btn-primary').button().click(function() {excuteCopy(obj, selectTree, action)})
				
				$(o.copymodal).on('hide.bs.modal', function () {
					$(o.copymodal).find('.btn-primary').unbind('click');
				});
			}
			
			var excuteCopy = function (obj, tree, action) {
				var destObj = tree.getSelectedObj();
				
				//sendCommand
				var postdata = {sourceid:obj.id,
						sourcetype:obj.type,
						destid: destObj.id,
						desttype: destObj.type,
						flag:action}
				
				sendCommand({
					script:'ajax/privatecontent/copy',
					postdata:postdata,
					callbackSuccess: function (parsedData) {
						if (parsedData.RESULT == true) {
							//please add code here
						}else return false;
					}
				});
			}

			var itemClick = function (i) {
				$(i).parent().find('.selector').removeClass('selected');
				$(i).parent().find('.selector').addClass('unselected');
				$(i).parent().find('.file-name').removeClass('selected');
				$(i).parent().find('.file-name').addClass('unselected');

				$(i).find('.file-name').removeClass('unselected');
				$(i).find('.file-name').addClass('selected');
				$(i).find('.selector').removeClass('unselected');
				$(i).find('.selector').addClass('selected');
				
				if ($(i).find('.file-name').text() != '')
					currentObj.name = $(i).find('.file-name').text();
				
				currentObj.id = $(i).attr('rel').substring(3);
				currentObj.type = $(i).find('>div>div').hasClass('icon-directory') ? 'directory':'file';
				var item = searchItemByID(currentObj.id, currentObj.type);
				currentObj.parentID = item.parentID;
			}
			
			var doubleClick = function (i) {
				var rel = $(i).attr('rel');
				if ($(i).hasClass('directory'))	{				
					var id = rel.substring(3, rel.length);
					o.curentParent = o.dirIDprefix + id;
					renderGrid(o);
					o.tree.openTreeOffset(id);
				}
			}
			
			var searchItemByID = function (itemID, type) {
				var source = (type == 'directory') ? o.directoryTreeData.DIRECTORIES : (type == 'file') ? o.directoryTreeData.FILES : null;
				var item = {};
				if (itemID == 0) {
					item.id = 0;
					item.parentID = 0;
					item.name = 'Home';
				}
				else {
					for (var i = 0 ; i < source.length; i++) {
						if (source[i].id == itemID) {
							item = source[i];
							break;
						}
					}
				}
				
				item.type = type;
				return item;
			}

			var renderGrid = function (o) {
				$(o.container).find ('.vscell').remove();
				
				var childDir = o.directoryTreeData.DIRECTORIES;
				var childFile = o.directoryTreeData.FILES;
				var currentDirID = o.curentParent.substring(o.dirIDprefix.length, o.curentParent.length);
				
				var disabledItemsList = ['preview','rename','copy','cut','delete','open'];
				var item = searchItemByID(currentDirID,'directory');
				
				$(o.container).contextMenu({
					menu: 'gridMenuParent',
					disabledItems: disabledItemsList
				}, function(action, el, pos) {
					switch(action) {
						case 'newfolder':
							openNewFolderModal(item);
							break;
						case 'share':
							showShareModal(item);
							break;
						default:
							break;
					}
				});
				
				for (var i = 0 ; i < childDir.length; i++) {
					if (childDir[i].parentID != currentDirID) continue;
					createNode ({
						id: childDir[i].id,
						name: childDir[i].name,
						parentID: currentDirID,
					});
				}
				
				for (var i = 0 ; i < childFile.length; i++) {
					if (childFile[i].parentID != currentDirID) continue;
					createNode ({
						id: childFile[i].id,
						name: childFile[i].name,
						parentID: currentDirID,
						minetype: childFile[i].minetype,
					});
				}
				
				keyboardRename();
				bindCreateFolder();
			}
			
			var rename = function (e) {
				var nameObj = $(e).find('.file-name');
				var editor = document.createElement ('INPUT');
				editor.type = 'text';
				editor.className = 'rename';
				
				$(nameObj).text('');
				$(nameObj).append(editor);
				
				$(editor).attr('value', currentObj.name);  
				editor.focus();
				$(editor).select();
				$(editor).bind('focusout',function (e) {
					cancelRename($(this).parent().parent());
				});
				
				$(editor).bind('keypress',function (e) {
			        var keycode = (e.keyCode ? e.keyCode : e.which);
			        if(keycode == '13'){
			        	completeRename($(this).parent());
			        }
			        else {
			        	
			        }
			        e.stopPropagation();
				});
			}
			
			var cancelRename = function (e) {
				$(e).find('INPUT.rename').remove();
				$(e).find('.file-name').text(currentObj.name);
			}
			
			var completeRename = function (e) {
				
				var postdata = {id:currentObj.id,
								objtype:currentObj.type,
								newname:$(e).find('INPUT.rename').val()}
				sendCommand({
					script:'ajax/privatecontent/rename',
					postdata:postdata,
					callbackSuccess: function (parsedData) {
						if (parsedData.RESULT == true) {
							currentObj.name = parsedData.UPDATED.name;
							$(e).find('INPUT.rename').remove();
							$(e).text(currentObj.name);
						}else return false;
					}
				});
			}
			
			var sendCommand = function (p) {
				if( p.postdata == undefined ) p.postdata = null;
				if( p.script == undefined ) p.script = o.script;
				if( p.callbackSuccess == undefined ) p.callbackSuccess = null;
				if( p.callbackDone == undefined ) p.callbackDone = null;
				if( p.callbackFail == undefined ) p.callbackFail = null;
				if( p.callbackAlways == undefined ) p.callbackAlways = null;

				if (p.script != null) {
					$.post(o.host + p.script, p.postdata, function (data){
						if (data) {
							parseData = $.parseJSON(data);
						}

						if (p.callbackSuccess != null) {
							p.callbackSuccess(parseData);
						}
					}).done(function() {if (p.callbackDone != null)p.callbackDone(this);}).fail(function() {if (p.callbackFail != null)p.callbackFail(this);}).always(function() {if (p.callbackAlways != null)p.callbackAlways(this);});
				}
			}

			this.setData = function (data) {
				o.directoryTreeData = data.directoryTreeData;
				o.curentParent = data.curentParent;
				o.dirIDprefix = data.dirIDprefix;
				renderGrid(o);
			}
			
			this.setTree = function (treeObj) {
				o.tree = treeObj;
			}
			
			this.showModal = function (obj, act) {
				switch( act ) {
					case 'newfolder':
						openNewFolderModal(obj);
						break;
					case 'copy':
					case 'cut':
						showCopyModal(obj, act);
						break;
					case 'share':
						showShareModal(obj);
						break;
					default:
						break;
				}
			}
			
			this.searchItem = function (id, type) {
				return searchItemByID (id, type);
			}

			this.initialize = function() {
        		return this;
    		};

			return this.initialize();
		}
	});

})(jQuery);