/******************************************************************************
 * @file jquery.hpsumBrowse.js
 *
 *
 * @section LICENSE
 *
 * HPE Confidential
 * Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
 *
 * @section DESCRIPTION
 *
 * This is a plugin for showing the Browse dialog to select a folder.
 *
 *
 *******************************************************************************/
define(['hp/core/EventDispatcher',
		'hp/core/Localizer', 
		'hp/view/DialogView',
		'hp/model/Session',
		'hpsum/presenter/baseline/BaselinePresenter',
		'text!hpsumpages/common/browse_dialog.html',   
		'jquery', 
		'lib/jquery.jstree'], 
function(EventDispatcher, localizer, DialogView, session, baselinePresenter, browseDialogHtml) {"use strict";
	(function($) {
		// Create the defaults once
  		var pluginName = "hpsumBrowse",
		BROWSE_TREE = "#browse",
		BROWSE_CREATEDIR = "#hpsum-browse-dialog-createdir",
		BROWSE_OK = "#hpsum-browse-dialog-ok",
		BROWSE_CANCEL = "#hpsum-browse-dialog-cancel",
		BROWSE_INFO_DIALOG = "#hpsum-browse-info-dialog",
		BROWSE_INFO_MESSAGE = "#hpsum-browse-info-message",
		BROWSE_INFO_DIALOG_BUTTON = "hpsum-browse-info-button-ok",
		B_SHOW_XML = "bshowXml",
		WINDOWS = "Win",
		output_file = '',
		init_location = '',
		browseDialogContents,
		MAX_COUNTER = 1024,
		ENTER_KEY = 13,
		ESC_KEY = 27,
		infoDialog,
		bEscKeyPressed = false,
		newnode = null,
		defaults = {
            options: null,
            panelLabel: "",
            panelHelp: "",
            panelBrowseText: localizer.getString("hpsum.common.browse"),
            bshowXml: false, //if true, shows the xml files
            bshowFile: false, //if true, shows all the files
            bShowHPSUMFiles: false, //if true, shows HPSUM related files
            bShowEmptyFolder: false, //if true, shows empty folder
	    	bCreateDirectory: false //if true, shows Create New Directory button
        };
				
    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.options = $.extend( {}, defaults, options );
		this.dispatcher = new EventDispatcher();
        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    Plugin.prototype = {

        init: function() {
			$(this.element).addClass('hpsumBrowse');
			if(this.options.command =='init') {
				this.createBrowsePanel(this.element, this.options);
           	}
        },
        //Adds lable, input and browse button as panel to the DIV element provided
        createBrowsePanel: function(element, options) {
        	
        	var plugin = this;
        	var idprepend = element.id + '-' + pluginName;

        	$(element).empty();
        	
        	if(options.hasOwnProperty("panelLabelStyle") && options.panelLabelStyle.length > 0)
        		$(element).before('<label id="' + idprepend + '-label"' + 'for="' + idprepend + '-input-text"' + 'data-localize="'+ options.panelLabel + '" style="' + options.panelLabelStyle + '">' + localizer.getString(options.panelLabel) + '</label>');
        	else
        		$(element).before('<label id="' + idprepend + '-label"' + 'for="' + idprepend + '-input-text"' + 'data-localize="'+ options.panelLabel + '">' + localizer.getString(options.panelLabel) + '</label>');
        	
        	var appendstr = '<input id="' + idprepend + '-input-text"' + 'type="text"/>';
        	
        	if(options.hasOwnProperty("panelButtonStyle") && options.panelButtonStyle.length > 0)
        		appendstr = appendstr + '<input id="' + idprepend + '-browse-button"' + 'class="hp-button hp-secondary" type="button" data-localize="' + options.panelBrowseText + '" value="' + localizer.getString(options.panelBrowseText) + '" style="' + options.panelButtonStyle + '"/>';
        	else
        		appendstr = appendstr + '<input id="' + idprepend + '-browse-button"' + 'class="hp-button hp-secondary" type="button" data-localize="' + options.panelBrowseText + '" value="' + localizer.getString(options.panelBrowseText) + '"/>';
        					 
        	if(options.hasOwnProperty("panelHelp") && options.panelHelp.length > 0)
        		appendstr = appendstr + '<label class="hp-help" data-localize="' + options.panelHelp + '">' + localizer.getString(options.panelHelp) + '</label>';
        	
        	$(element).append(appendstr);
        	
        	//Default behaviour for Browse button click
        	//Shows the browse dialog with the directory heirarchy
       		$('#' + idprepend + '-browse-button').off('click').on('click', function () {
       				if(plugin.options.hasOwnProperty("onBrowseButtonClick"))
	        		{
	        			plugin.setBrowseButtonClick();
	        		}
                  	plugin.showBrowseDialog(element, options);
            });
            
            //optional event handlers
            if(options.hasOwnProperty("enableActionButtons"))
            {
	            $('#' + idprepend + '-input-text').blur(function(){
					plugin.onBlur();
	          	});
	        }
        },
        //returns the currently selected node from JSTree
        getSelectedItem:function(){
        	
        	var node = $(BROWSE_TREE).jstree('get_selected');
			if(node[0] == null)
			{
				return "";
			}
			
			output_file = node[0].id;
					
			return output_file;
        },
        //returns the currently selected item from Input element
        getLocation:function() {
        	var idprepend = this.element.id + '-' + pluginName;
        	return $('#' + idprepend + '-input-text').val();
        },
        //returns if selected node is package or not
        isPackage:function(){
        	var node = $(BROWSE_TREE).jstree('get_selected');
			if(node[0] && node[0].attributes["rel"].value == "package")
        		return true;
        	else
        		return false;
        },
        //sets the label contents 
        setPanelLabel:function(newLabel) {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-label').html(newLabel);
        },
        //sets the input contents
        setPanelText:function(newVal) {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-input-text').val(newVal);
        },
        setInputAttr:function(attrname, val) {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-input-text').attr(attrname, val);
        },
        removeInputAttr:function(attrname) {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-input-text').removeAttr(attrname);
        },
        setLocationType:function(newLocType) {
        	this.options.location_type = newLocType;
        },
        addInputClass:function(newClass) {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-input-text').addClass(newClass);
        },
        removeInputClass:function(newClass) {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-input-text').removeClass(newClass);
        },
        //event handler for the input element
        setInputEvent:function(eventname, func){
        	var idprepend = this.element.id + '-' + pluginName;
        	if(eventname == 'onchange'){
        		$('#' + idprepend + '-input-text').off('change').on('change', func);
        	}
        	else if(eventname == 'onkeyup'){
        		$('#' + idprepend + '-input-text').keyup(func);
        	}
        	else if(eventname == 'offkeyup'){
        		$('#' + idprepend + '-input-text').unbind('keyup', func);
			}
        	else if(eventname == 'oninput'){
        		$('#' + idprepend + '-input-text').off('input').on('input', func);
			}
			else if(eventname == 'onfocusout'){
        		$('#' + idprepend + '-input-text').focusout(func);
			}
			else if(eventname == 'onfocus'){
        		$('#' + idprepend + '-input-text').focus(func);
			}
			else if(eventname == 'onfocusin'){
        		$('#' + idprepend + '-input-text').focus(func);
			}
        },
        //triggers a particular event for the input event
        triggerInputEvent: function(eventname) {
        	var idprepend = this.element.id + '-' + pluginName;
			if(eventname == 'change')
				$('#' + idprepend + '-input-text').trigger('change');
		},
		//triggers a particular event for the browse dialog buttons
        triggerDialogEvent: function(eventname) {
			if(eventname == 'clickcancel')
				$(BROWSE_CANCEL).trigger('click');
			if(eventname == 'clickok')
				$(BROWSE_OK).trigger('click');
			if(eventname == 'createdir')
				$(BROWSE_CREATEDIR).trigger('click');
		},
		//browse dialog attributes support functions
		setDialogAttr:function(elementname, attrname, val) {
        	if(elementname == 'ok')
        		$(BROWSE_OK).attr(attrname, val);
        	if(elementname == 'cancel')
        		$(BROWSE_CANCEL).attr(attrname, val);
			if(elementname == 'createdir')
        		$(BROWSE_CREATEDIR).attr(attrname, val);
        },
        removeDialogAttr:function(elementname, attrname) {
        	if(elementname == 'ok')
        		$(BROWSE_OK).removeAttr(attrname);
        	if(elementname == 'cancel')
        		$(BROWSE_CANCEL).removeAttr(attrname);
			if(elementname == 'createdir')
        		$(BROWSE_CREATEDIR).removeAttr(attrname);
        },
		// Returns the child element for specified id
        getChild: function (child) {
		    return $('#' + child);
		},
		// Sets focus for the Input element
        setFocus:function() {
        	var idprepend = this.element.id + '-' + pluginName;
        	$('#' + idprepend + '-input-text').focus();
        },
        //generates unique folder name similar to Windows 
        generateUniqueFolderName: function(nodes) {
			var dirname;
		    for(var index=0; index < MAX_COUNTER; index++) {
		    	dirname = localizer.getString("hpsum.common.newdir") + " " + index;
		    	if(this.checkFolderExists(dirname, nodes)) {
		    		continue;
		    	}	
		    	else {
		    		break;
		    	}
		    }
		    	
		    return dirname;
		},
		//Verifies if a specific folder name already exists in current parent folder
		checkFolderExists: function(dirname, nodes) {
			var isFolderExists = false;
			for (var index = 0; index < nodes.length; index++) {
		    	var folder_name = nodes[index].id;
		    	if(folder_name.indexOf('/') != -1)
					folder_name = folder_name.substring(folder_name.lastIndexOf('/')+1);
				else
					folder_name = folder_name.substring(folder_name.lastIndexOf('\\')+1);
				
				//Ignore case on Windows while comparing entered and existing folder names 
				if(navigator.appVersion.indexOf(WINDOWS) != -1) {
					 var regex = new RegExp('^' + folder_name + '$', 'i');

					if (regex.test(dirname)) {
						isFolderExists = true;
			        	break;	
					}
				}
				else {
					//Compare for exact folder names on linux
			        if(dirname == folder_name) {
			        	isFolderExists = true;
			        	break;
			        }
			   	}
		    }
		    
		    return isFolderExists;
		},
        //Displays the browse dialog
        showBrowseDialog:function(element, options) {
			browseDialogContents = $(browseDialogHtml);
			var plugin = this;
			if(options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true)
			{
				if ( navigator.appVersion.indexOf(WINDOWS) != -1 )
				{
					var str = plugin.element.childNodes[0].value;
					var xmlfile = str.split("\\").pop();
					plugin.element.childNodes[0].value = str.replace('\\' + xmlfile, "");			
				}
				else
				{
					var str = plugin.element.childNodes[0].value;
					var xmlfile = str.split("/").pop();
					plugin.element.childNodes[0].value = str.replace('/' + xmlfile, "");
				}
			}
			var pluginOptions = options;
			var idprepend = element.id + '-' + pluginName;
        	var locid = '#' + idprepend + '-input-text';
			localizer.localizeDom(browseDialogContents);
			//show component dialog
			var dialog = new DialogView();
			dialog.init({contents: browseDialogContents,
				ok: function (elem) {
					var node = $(BROWSE_TREE).jstree('get_selected');
					if(node.length == 0)
					{
                    	node=node.prevObject;
					}
					if(node[0] == null)
					{
						if(options.hasOwnProperty("onNoSelection")) {
							plugin.setNoSelection();
						}
						return false;
					}
					
					if(options.hasOwnProperty("onInvalidPackageSelection")) {
						if(node[0] == null || (node[0] && node[0].attributes["rel"].value != "package"))
	                	{
	                		if(options.hasOwnProperty("location_type") && options.location_type == 'local')
	                		{
	                			plugin.setInvalidPackageSelection();
	                    		return false;
	                		}
	                	}
	                }
					
				    //auto selecting newly created folder as Output Location.
					
					if (node[0] != null)
					{
					    //assign first the selected folder. later check if newly created folder is available in next condition. 
						output_file = node[0].id; 
					}
					if(node.length > 1 && node[1].id == '')
					{
						var newCreatedfolder = node[1].lastChild.innerText.trim();
						output_file = node[0].id + '/' + newCreatedfolder;
					}
					
					var path;
					if(options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true)
					{
						path = $(locid).val();
	                }
					else 
					{					
						$(locid).val(output_file);
					}
                	path = $(locid).val();
                	path = path.replace("_C_", ":");
                	if (path[0] != '/' && navigator.appVersion.indexOf(WINDOWS) != -1)
					{
						var repSlash1 = path.split('\\').join('');
						path = repSlash1.split('/').join('\\');
 					}
					else
					{
						path = path.split('\\').join('');
					}
					$(locid).val(path);
					$('#hpsum-baseline-add-browse-hpsumBrowse-input-text').attr('tooltip', path).hpTooltip();
					$('#hpsum-custom-baselines-targetloc-hpsumBrowse-input-text').attr('tooltip', path).hpTooltip();
					$('#hpsum-report-browse-panel-hpsumBrowse-input-text').attr('tooltip', path).hpTooltip();
					$(locid).trigger("change");
					$(locid).focus();
					if(options.hasOwnProperty("onBrowseDone"))
						plugin.setBrowseDone();
				},
				cancel: function () {
					output_file = '';
					$(locid).val(init_location);
					$(locid).focus();
					if(options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true)
					{
						if ( navigator.appVersion.indexOf(WINDOWS) != -1 )
						{
							$(locid).val(init_location  + '\\' + xmlfile);
							$(locid).focus();
						}
						else
						{
							$(locid).val(init_location  + '/' + xmlfile);
							$(locid).focus();
						}
	                }
					if(options.hasOwnProperty("onBrowseCancel"))
						plugin.setBrowseCancel();
				}
				
				});
			
			//Show "Create New Directory" option and register for click event only if option is set	 
			if(options.hasOwnProperty("bCreateDirectory") && options.bCreateDirectory == true) {
				$(BROWSE_CREATEDIR, browseDialogContents).show();
				$(BROWSE_CREATEDIR, browseDialogContents).off("click").on("click", function(event){
						var node = $(BROWSE_TREE).jstree("get_selected");
						if(node.length == 0)
						{
	                    	node=node.prevObject;
						}
						if(node[0] != null && node[0].id != "..")
						{
							bEscKeyPressed = false;
							var nodes = jQuery.jstree._reference(BROWSE_TREE)._get_children(node);
						    var newfolder = plugin.generateUniqueFolderName(nodes);
						    newnode = null;
						    newnode = $.jstree._reference(BROWSE_TREE).create(null, 'child', newfolder);
						    //move focus to new node
						    if(newnode) {
						    	$(BROWSE_TREE).jstree('select_node', newnode, false);
						    }
						    $(BROWSE_CREATEDIR, browseDialogContents).attr('disabled', 'disabled');
						}
				});
			}
			else {
				$(BROWSE_CREATEDIR, browseDialogContents).hide();
			}
		
			this.createtree(this.element, this.options);
			$(BROWSE_OK).attr("disabled", "disabled");
			
			$(document).on('keydown', (function(event) {
				var keycode = (event.keyCode ? event.keyCode : event.which);
			    if(keycode == ENTER_KEY) {
			        var target;
					target = event.target || event.srcElement;
										
					if($(target).hasClass("jstree-rename-input") == false &&
						target.id != BROWSE_INFO_DIALOG_BUTTON) {
						$(BROWSE_OK).trigger('click');
					}
			    }
			}));
		},
		//show error or info message in a separate dialog box
		showInfoDialog: function(msg)
        {
        	if (!infoDialog) {
                infoDialog =  $(BROWSE_INFO_DIALOG);
                infoDialog.dialog({
                    modal : true,
                    dialogClass: 'hp-simple-dialog',
                    position : "center",
                    draggable : false,
                    resizable : false
                });
                $('#' + BROWSE_INFO_DIALOG_BUTTON).on('click', function (event) {
                    infoDialog.dialog('close');
                });
            }
            if(msg == undefined) {
				msg = "";
			}
			$(BROWSE_INFO_MESSAGE, infoDialog).html(msg);
			msg='';
            infoDialog.dialog('open');
       	},
		//optional customization support functions
		setChanged: function(selectedPath){
			this.options.onSelectionChanged(selectedPath);
		},
		onBlur: function() {
			this.options.enableActionButtons();
		},
		setBrowseDone: function() {
			this.options.onBrowseDone();
		},
		setBrowseCancel: function() {
			this.options.onBrowseCancel();
		},
		//This function is used to override the default browse button click event
		//Using this we can perform different operation instead of showing default Browse dialog 
		setBrowseButtonEvent:function(eventname, func){
			var plugin = this;
			var browseid = '#' + this.element.id + '-' + pluginName + '-browse-button';
        	
        	if(eventname == 'default') {
	        	$(browseid).off('click').on('click', function () {
	        		if(plugin.options.hasOwnProperty("onBrowseButtonClick"))
	        		{
	        			plugin.setBrowseButtonClick();
	        		}
                  	plugin.showBrowseDialog(plugin.element, plugin.options);
            	});
	    	}
	    	
        	if(eventname == 'onclick') {
        		if(plugin.options.hasOwnProperty("onBrowseButtonClick"))
        		{
        			plugin.setBrowseButtonClick();
        		}
	        	$(browseid).off('click').on('click', func);
	    	}
        },
        //Browse button configurable functions
        setBrowseButtonText: function(newVal) {
        	var browseid = '#' + this.element.id + '-' + pluginName + '-browse-button';
        	$(browseid).val(newVal);
        },
        setBrowseButtonClick: function() {
        	this.options.onBrowseButtonClick();
        },
        //Call back function helpers which can be called from consumer
		setInvalidPackageSelection: function() {
			this.options.onInvalidPackageSelection();
		},
		setNoSelection: function() {
			this.options.onNoSelection();
		},
		setOnSelectNode: function(selectedVal, nodeType) {
			this.options.onSelectNode(selectedVal, nodeType);
		},
		recreatetree:function() {
			this.createtree(this.element,this.options);
		},
		setHandleInvalidPath: function(output) {
			this.options.onHandleInvalidPath(output);
		},
		setBrowseOptions: function (newoptions) {
			$.extend( this.options, newoptions );
		},
		//Creates the jstree and shows the drives, folders, packages and files in a heirarchy
        createtree: function(el, options) {
        	var plugin =this;
			var id = '';
            $('#hpsum-browse-dialog-emptyfoldericon').hide();
            var idprepend = el.id + '-' + pluginName;
        	
			id = '#' + idprepend + '-input-text';
			
			var uri = "Session/" + session.getToken()  + "/Baseline/browse";
			
			init_location = $(id).val();
			var initial_folder = $(id).val();
			// For windows when user enter backslash replace with farwardslash due to backslash take more time bring up
			if ( navigator.appVersion.indexOf(WINDOWS) != -1  && initial_folder.indexOf("\\") == 0 ) 
			{
				$(id).val("/");
				initial_folder = "/";
			}
			
			$(BROWSE_TREE).empty();
			$(BROWSE_TREE).jstree({
					"json_data" : {
							   "ajax" : {
									"url" : function (node) {
										var url;
										if (node == -1) {
											url = "Session/" + session.getToken()  + "/Baseline/browse";
										} else {
											url = null;
										}
										return url;
									},
									"type" : "POST",
									"dataType" : "json",
									"data" : function (n) { 
											
											var uri = $(id).val().length > 0 ? $(id).val() : "..";
											if(uri.match('/'))
											{
												uri = uri.split('\\').join('');
											}
					
											uri = uri.replace("_C_", ":");
											var object;
											if(options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true)
											{
												object = {
													"hapi": {
														"uri": uri,
														"showXml": true
													}
												};
											}
											else if(options.hasOwnProperty("bshowFile") && options.bshowFile == true) 
											{
												object = {
													"hapi": {
														"uri": uri, 
														"show_file": true
													}
												}; 
											}
											else if(options.hasOwnProperty("bShowHPSUMFiles") && options.bShowHPSUMFiles == true) 
											{
												object = {
													"hapi": {
														"uri": uri, 
														"show_hpsum_file": true
													}
												}; 
											}
											else if(options.hasOwnProperty("bShowEmptyFolder") && options.bShowEmptyFolder == true) 
											{
												object = {
													"hapi": {
														"uri": uri, 
														"show_empty_folder": true
													}
												};
												$('#hpsum-browse-dialog-emptyfoldericon').show();						
											}
											else {
												object = {
													"hapi": {
														"uri": uri
													}
												};
											}
											
											return JSON.stringify(object); 
									},
									"success" : function (output) {
										
										var data = [], children = [], index, node, bAddParent = false;
										
										if(options.hasOwnProperty("onHandleInvalidPath"))
										{
											plugin.setHandleInvalidPath(output.hapi);
										}
										
										//hcode has string value in the response payload. This need to be changed later when it is 
										//changed to integer value
										if(output.hapi.hcode != "0" || output.hapi.folders.folder.length <= 0)
										{
											//add a node to navigate to parent directory 
											node = {
														"data" : "..",
														"attr" : { "id" : "..", "rel" : "parent"},
														"state" : "open"
													   };
													   
											data.push( node );
											return data;
										}
										
										//iterate through folders and create child nodes
										for(var i=0; i < output.hapi.folders.folder.length; i++ ){
											var folder = output.hapi.folders.folder[i];
											var child, rel;
											
											if(i === 0) 
											{
												var str = $(id).val();
												bAddParent = true;
											}	
											
											//if it is root folder and drive, add the first item as a sibling node instead of parent node
											//change icon if folder is a valid package
											if(folder.possible_package)
												rel = "package";
											else
												rel = "folder";
											
											//take only last folder name from complete path
											//var str = folder.folder_name.substring(folder.folder_name.lastIndexOf('/')+1);
											var strfolder, idfolder;
											if(str === '/' && folder.folder_name.indexOf('/') != 0) {
												strfolder = folder.folder_name.substring(0, folder.folder_name.indexOf('/')-1);
												idfolder = folder.folder_name.substring(0, folder.folder_name.indexOf('/'));
											}
											else {
												if(folder.folder_name.indexOf('/') != -1)
													strfolder = folder.folder_name.substring(folder.folder_name.lastIndexOf('/')+1);
												else
													strfolder = folder.folder_name.substring(folder.folder_name.lastIndexOf('\\')+1);
													
												idfolder = folder.folder_name;
											}
											idfolder = idfolder.replace(":", "_C_");
											idfolder = idfolder.replace(/[-[\]{}&@()*+!<=?^$;%^'|#,]/g, '\\$&'); 
											//create children nodes
											if ( i > 0 || str === '/' ) {
												if(strfolder.length > 0 && idfolder.length > 0) {
													child = {
														"data" : strfolder,
														 "attr" : {"id" : idfolder, "rel" : rel}
														};
													children.push( child );
												}
											}
										}
										
										//add a node to navigate to parent directory 
										node = {
													"data" : "..",
													"attr" : { "id" : "..", "rel" : "parent"},
													"state" : "open"
												   };
										
										//show files if bshowFile is true
										if(options.hasOwnProperty("bshowFile") && options.bshowFile == true) 
										{	   
											// add file node into node list
											var currFolder = output.hapi.folders.folder[0].folder_name;
											var fileRel = "file";
											for(var i=0; i < output.hapi.files.length; i++ ){
												var fileName = output.hapi.files[i];
												var fileFullPath = currFolder+"/"+fileName;
													
												//create children nodes
									        	child = {
									        		"data" : fileName,
									        		 "attr" : {"id" : fileFullPath, "rel" : fileRel}
									        		};
										        children.push( child );
										    }
										}
												   
										if(bAddParent) {
											var rel, val;
											if(output.hapi.folders.folder[0].possible_package)
												rel = "package";
											else
												rel = "folder";
												
											if($(id).val() === '')
												val = output.hapi.folders.folder[0].folder_name;
											else
											{
												
												if ( initial_folder.length > 0 ) 
												{
													var repSlash = $(id).val().split('\\').join('/');
													val = repSlash.replace(/[-[\]{}@&()&*+!<=?^$;%^'|#,]/g, '\\$&');
													initial_folder="";
												}
												else
													val = $(id).val();
												
											}
												
											var valId = val; 
											valId = valId.replace(":", "_C_");
											val = val.replace("_C_", ":");
											if ( val =='/' && navigator.appVersion.indexOf(WINDOWS) != -1  )   
											{
												val = "";
												rel = "folder";
												if (valId!= '/')
												{
													val = valId;
													data.push( node );
												}
											}
											else
											{
												if ( val != '/' )
												data.push( node );
											}
											if ( val[0] != '/' && navigator.appVersion.indexOf(WINDOWS) != -1 )
											{
												val = val.split('\\').join('');
												var repSlash1 = val.split('/').join('\\');
												val = repSlash1;				
											}
											else
											{
												val = val.split('\\').join('');
											}
											
											//add parent folder to folder list
											node = {
														"data" : val,//output.hapi.folders.folder[0].folder_name,
														"attr" : { "id" : valId, "rel" : rel}, //{ "id" : output.hapi.folders.folder[0].folder_name, "rel" : rel},
														"metadata" :  output.hapi.folders.folder[0],
														"state" : "open",
														"children" : children
													   };
													   
											data.push( node );
										}
										else
										{
											data.push(children);
										}
										
													
										return data;
									}
							   }
					},
					"themes" : {
							"theme" : "default",
							"url" : "/css/style.css",
							"dots" : true,
							"icons" : true
					},
					"core" : {
				      animation : 0,
				      strings : {
				        new_node : localizer.getString("hpsum.common.newdir"), //this text will change the label when you create a new node
				      }
				    },
					"plugins" : [ "themes", "json_data", "ui" , "crrm", "types" ],
					"ui" : {
						"select_limit": 1
					},
					"types" : {
							"max_depth" : -2,
							"max_children" : -2,
							"valid_children" : [ "drive" ],
							"types" : {
									"default" : {
											"valid_children" : "none",
											"icon" : {
													"image" : "/img/hp-piano/collapse-closed.png"
											}
									},
									"folder" : {
											"valid_children" : [ "default", "folder", "package", "file" ],
											"icon" : {
													"image" : "/img/hp-piano/collapse-closed.png"
											}
									},
									"package" : {
											"valid_children" : [ "default", "folder" ],
											"icon" : {
													"image" : "/img/hp-piano/status-ok.png"
											}
									},
									"file" : {
                                            "valid_children" : "none",
                                            "icon" : {
                                                    "image" : "/img/hp-piano/status-ok-small.png"
                                            }
                                    },
									"drive" : {
											"valid_children" : [ "default", "folder", "file" ],
											"icon" : {
													"image" : "/img/hp-piano/down-arrow.png"
											},
											"start_drag" : false,
											"move_node" : false,
											"delete_node" : false,
											"remove" : false
									},
									"parent" : {
											"valid_children" : [ "default", "folder", "drive", "package", "file" ],
											"icon" : {
													"image" : "/img/hp-piano/grid-collapse.png"
											},
											"start_drag" : false,
											"move_node" : false,
											"delete_node" : false,
											"remove" : false
									}
									
							}
					}
			})
			.bind("click.jstree", function (event, data) {
					if(options.hasOwnProperty("bCreateDirectory") && options.bCreateDirectory == true) {
						var target = event.target || event.srcElement;
						if($(target).hasClass("jstree-rename-input") == true) {
							return false;
						}
					}
					var node = $(BROWSE_TREE).jstree('get_selected');
					if(node[0] == null)
						return;
					if(options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true)
					{
						var xmlname = node[0].id;
	            		if (xmlname.match(".xml$"))
	            			return;
	            	}
	            	
	            	var rel = node[0].attributes.rel.value;
	            	if(options.hasOwnProperty("bshowFile") && options.bshowFile == true && rel == "file")
					{
						return;
					}
					if(node[0].id === "..")
					{
						if(node[0].nextSibling)
						{
							var str = $(id).val(); 
							if(str === '')
							{
								$(id).val(node[0].nextSibling.id.substring(0, node[0].nextSibling.id.lastIndexOf("/")));
								$(id).trigger('change');
							}
							else if(str === '/')
							{
								
							}
							else
							{
								if(str.indexOf('/') != -1 || (str.indexOf('\\') != -1)){
									$(id).val(node[0].nextSibling.id.substring(0, node[0].nextSibling.id.split('\\').join('').lastIndexOf("\\")));
									if($(id).val() == "")
									{
										$(id).val(node[0].nextSibling.id.substring(0, node[0].nextSibling.id.lastIndexOf("/")));
									}
									
									var root_path = $(id).val();
									if ( root_path == '' )
										$(id).val("/");
									$(id).trigger('change');	
								}
								else {
									$(id).val("/");
									$(id).trigger('change');
								}
							}
						}
						else
						{
							$(id).val("/");
							$(id).trigger('change');
						}
					}
					else 
					{	
						
						if(node[0].id == "/") 
						{
							$(id).val(node[0].id);
                    	                        }
						else
						{
							$(id).val(node[0].id);
							var path = $(id).val();
		                	path = path.replace("_C_", ":");
		                	if ( path[0] != '/' && navigator.appVersion.indexOf(WINDOWS) != -1 )
							{
								var repSlash1 = path.split('/[\]/g').join('');
								path = repSlash1;			
							}
							$(id).val(path);
						}
						
						$(id).trigger('change');
					}
					
					$(BROWSE_TREE).jstree("refresh");
			})
			.bind("reselect.jstree", function (event, data) {
				//we loose the selection when jstree is refreshed, so selecting the first folder by default
				$(BROWSE_TREE).jstree('select_node', 'ul:last', true);
				var node = $(BROWSE_TREE).jstree('get_selected');
				if(node.length == 0 || $(node[0]).hasClass('jstree-leaf')) {
					$(BROWSE_TREE).jstree('select_node', 'ul > li:last', true);
				}
				if(options.hasOwnProperty("bCreateDirectory") && options.bCreateDirectory == true) {
					$(BROWSE_CREATEDIR, browseDialogContents).removeAttr('disabled');
				}
			})
			.bind("rename_node.jstree", function (event, data) {
				if(options.hasOwnProperty("bCreateDirectory") && options.bCreateDirectory == true && !bEscKeyPressed) {
					//Validate folder name and show error message if invalid characters are entered  
					if((/:|\?|\\|\*|\"|<|>|\||%/g.test(data.args[1]))) {
						plugin.showInfoDialog(localizer.getString("hpsum.common.newdirError"));
						$(BROWSE_CREATEDIR, browseDialogContents).removeAttr('disabled');
						$(BROWSE_TREE).jstree("refresh");
						return false;
					}
					var node = $(BROWSE_TREE).jstree('get_selected');
					if(node[0] == null)
						return;
					var nodevalue = node[0].id;
					
					nodevalue = nodevalue.replace("_C_", ":");
					nodevalue = nodevalue.split('\\').join('');
					
					var object = {
						"hapi": {
							"uri": nodevalue,
							"new_dir": data.args[1]
						}
					};
					
					//Placeholder to handler the response if needed in future.
					var handlers = {
							success : function(data) {
	                            //Handle success scenario
	                            $(BROWSE_CREATEDIR, browseDialogContents).removeAttr('disabled');
	                            //if failed to created folder, then hcode is non-zero, hence show the error message to user
	                            if(data.hapi.hcode != 0) {
	                            	plugin.showInfoDialog(data.hapi.hmessage);
	                            }
	                            
	                            $(BROWSE_TREE).jstree("refresh");
	                        },
	                        error : function(errorInfo) {
	                            //handle failure scenario
	                            $(BROWSE_CREATEDIR, browseDialogContents).removeAttr('disabled');
	                        }
	                   };
	                   
					baselinePresenter.createDirectory(object, handlers);
				}
			})
			
			.bind("select_node.jstree", function (event, data) { 
				var node = $(BROWSE_TREE).jstree('get_selected');
				if(node[0] == null) {
					$(BROWSE_OK).removeAttr("disabled");
					return;
				}
				var nodetype = node[0].attributes["rel"].value;
				var nodevalue = node[0].id;
				
				if(options.hasOwnProperty("onSelectNode"))
				{
					plugin.setOnSelectNode(nodevalue, nodetype);
				}
				else
				{
					if(options.hasOwnProperty("bshowFile") && options.bshowFile == true && nodetype == "file")
					{
						$(BROWSE_OK).removeAttr("disabled");
						return;
					}
					else if(options.hasOwnProperty("bshowFile") && options.bshowFile == true && nodetype != "file")
					{
						$(BROWSE_OK).attr("disabled","disabled");
						return;
					}
						
					if (options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true && nodevalue.match(".xml$"))
					{
						$(BROWSE_OK).removeAttr("disabled");
						return;
					}
					else if (options.hasOwnProperty(B_SHOW_XML) && options.bshowXml == true && !nodevalue.match(".xml$"))
					{
						$(BROWSE_OK).attr("disabled","disabled");
						return;
					}
					
					if(nodetype != "folder" && nodetype != "package")
						$(BROWSE_OK).attr("disabled","disabled");
					else
						$(BROWSE_OK).removeAttr("disabled");
				}
				});
				
				//handle 'Enter' key event for JStree node after user entered new folder name and pressed Enter key
				//handle 'ESC' key event for JStree node to ignore new folder creation when ESC key pressed 
				$(BROWSE_TREE).on("keydown", ".jstree-leaf", function(event) {
					var keycode = (event.keyCode ? event.keyCode : event.which);
			    	bEscKeyPressed = false;
					if(keycode === ENTER_KEY) {
				    	$(this).jstree("rename");
				  	}
				  	if(keycode === ESC_KEY) {
				    	bEscKeyPressed = true;
				  	}
				});
		},
        destroy: function(el){
        		$(this.element).removeClass('hpsumBrowse');
        		$.removeData(this.element, "plugin_" + pluginName);
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function ( options ) {
    	var instance;
    	if ( typeof options === 'string' ) { 
                // call method
                var args = Array.prototype.slice.call( arguments, 1 );
				 this.each(function() {
                    instance = $.data( this, "plugin_" + pluginName );
                    if ( !instance ) {
                        if (window.console) {
                            window.console.error( "cannot call methods on hpsumBrowse prior to initialization; " +
                                "attempted to call method '" + options + "'" );
                        }
                        return;
                    }
                    if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
                        if (window.console) {
                            window.console.error( "no such method '" + options + "' for hpsumBrowse instance" );
                        }
                        return;
                    }
                    // apply method
                   	instance[ options ].call( instance, args );
                });  
              }
               else{
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin( this, options ));
               }

        });
        }
    };

}(jQuery));
});