/* <copyright>
This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
(c) Copyright 2011 Motorola Mobility, Inc.  All Rights Reserved.
</copyright> */

var Montage = require("montage/core/core").Montage,
    Component = require("montage/ui/component").Component,
    iconsListModule = require("js/components/ui/icon-list-basic/iconsList.reel"),
    treeModule = require("js/components/ui/tree-basic/tree.reel");

var PickerNavigator = exports.PickerNavigator = Montage.create(Component, {

    popup:{
        enumerable: false,
        writable: true,
        value: null
    },

    mainContentData:{
        enumerable:false,
        writable:true,
        value:null
    },

    _firstTime: {
        enumerable: false,
        value: true
    },

    firstTime:{
        get: function(){},
        set: function(){}
    },

    pickerCallback:{
        enumerable:false,
        writable:true,
        value:null
    },

    selectedItems:{//passed to pickerCallback on click of OK
        enumerable:false,
        writable:true,
        value:[]
    },

    /**
     * store a reference to the currently selected node... for single selection
     */
     currentSelectedNode:{
        enumerable:false,
        writable:true,
        value:null
    },

    currentURI:{
        enumerable:false,
        writable:true,
        value:null
    },

    iconsViewDrawnOnce:{
        enumerable:false,
        writable:true,
        value:false
    },

    /**
     * for tree view only
     * will store folder uri vs tree instance map
     */
    treeRefHash:{
        enumerable:false,
        writable:true,
        value:{

        }
    },

    selectedPickerView:{
        enumerable:false,
        writable:true,
        value:null
    },

    /**
     * Contains the different Views and their update handlers
     */
    pickerViews:{
        enumerable:false,
        writable:true,
        value: function(){
            var that = this;
            return {
                "iconView":that.updateIconView,
                "treeView":that.updateTreeView
            }
        }
    },
    
    pickerModel:{
        enumerable:false,
        writable:true,
        value:null
    },

    willDraw: {
    	enumerable: false,
    	value: function() {

    	}
    },
    draw: {
    	enumerable: false,
    	value: function() {
            this.filterVal.innerHTML = this.pickerModel.currentFilter;

            if(this.pickerModel.fatalError !== null){
                this.error.innerHTML = this.pickerModel.fatalError;
            }

    	}
    },
    didDraw: {
    	enumerable: false,
    	value: function() {

            var that = this;
            this.iconList = null;
            this.newContent = null;
            this.spanEl = null;

            this.addIdentifiers();

            var topLevelDirs = this.pickerModel.topLevelDirectories;
            var leftNav = this.leftNav;
            //draw left nav
            if(!!topLevelDirs
                && (typeof topLevelDirs === "object")
                && ('splice' in topLevelDirs)
                && ('join' in topLevelDirs)
                &&(topLevelDirs.length > 0)){

                topLevelDirs.forEach(function(dirObj){
                    var newDiv = document.createElement("div");
                    newDiv.className = "driversList";
                    newDiv.innerHTML = dirObj.name;
                    leftNav.appendChild(newDiv);
                    if(dirObj.uri === this.pickerModel.currentRoot){
                        newDiv.classList.add("highlighted");
                        //enable ok for logical drive selections, when in directory selection mode
                        if(this.pickerModel.inFileMode === false){
                            this.okButton.removeAttribute("disabled");
                            //put into selectedItems..currently single selection is supported
                            this.selectedItems = [dirObj.uri];
                        }
                    }

                    newDiv.addEventListener("click", function(evt){that.handleTopLevelDirectoryClicks(evt, dirObj);}, false);
                }, that);
            }else{
                console.error("need at least 1 valid top level directory");
            }

            //Draw icon view list
            //TODO: check the default view and draw the appropriate view
            if(this.mainContentData !== null){

                this.currentURI = this.pickerModel.currentRoot;

                //draw the IconsList if icons view container is on
                if(this.iconViewContainer.style.display === "block"){
                    this.iconList = iconsListModule.IconsList.create();
                    //console.log(this.mainContentData);
                    this.iconList.iconsViewDataObject = this.mainContentData;
                    this.iconList.element = this.iconViewContainer;
                    this.iconList.needsDraw = true;
                    this.iconsViewDrawnOnce = true;
                    this.selectedPickerView = "iconView";

                    if(!this.iconView.classList.contains("viewSelected")){
                        this.iconView.classList.add("viewSelected")
                    }
                    if(this.treeView.classList.contains("viewSelected")){
                        this.treeView.classList.remove("viewSelected");
                    }

                }else if(this.treeViewContainer.style.display === "block"){
                    //else draw the Tree if tree view container is on
                    this.renderTree(this.treeViewContainer, this.currentURI);
                    this.selectedPickerView = "treeView";

                    if(!this.treeView.classList.contains("viewSelected")){
                        this.treeView.classList.add("viewSelected")
                    }
                    if(this.iconView.classList.contains("viewSelected")){
                        this.iconView.classList.remove("viewSelected");
                    }
                }

                this.updateAddressBar(this.pickerModel.currentRoot);
                this.pickerModel.storeHistory(this.pickerModel.currentRoot);//populate history

                this.updateMetadata(this.currentURI);

                //for directory selection, selected url is the folder entered
                if(!this.pickerModel.inFileMode ){
                    this.okButton.removeAttribute("disabled");
                    //put into selectedItems..currently single selection is supported
                    this.selectedItems = [this.pickerModel.currentRoot];
                }
            }

            this.element.addEventListener("openFolder", function(evt){that.handlePickerNavOpenFolder(evt);}, false);//add icon double click event listener to reload iconList with new set of data
            this.element.addEventListener("selectedItem", function(evt){that.handlePickerNavSelectedItem(evt);}, false);//for single selection only
            this.element.addEventListener("selectFile", function(evt){that.handlePickerNavSelectedFile(evt);}, false);//for file selection
            this.element.addEventListener("showMetadata", function(evt){that.handlePickerNavShowMetadata(evt);}, false);//show metadata on hover of icon
            this.element.addEventListener("updateMetadata", function(evt){that.handlePickerNavUpdateMetadata(evt);}, false);//show metadata on click of icon
            //this.addressGo.addEventListener("click", this, false);
            this.addressBarUri.addEventListener("keydown", this, false);
            this.addressBarUri.addEventListener("keyup", this, false);
            this.refreshButton.addEventListener("click", this, false);//refresh - gets from file system directly
            this.backArrow.addEventListener("click", this, false);
            this.forwardArrow.addEventListener("click", this, false);

            //populate filters if in file selection mode
            if(this.pickerModel.inFileMode === true){
                var filtersDD = this.element.querySelector(".filters .dropdown");
                if(!!this.pickerModel.fileFilters
                    && (typeof this.pickerModel.fileFilters === "object")
                    && ('splice' in this.pickerModel.fileFilters)
                    && ('join' in this.pickerModel.fileFilters)){
                    this.pickerModel.fileFilters.forEach(function(aFilter){
                        var newDiv = document.createElement("div");
                        newDiv.innerHTML = aFilter;
                        filtersDD.appendChild(newDiv);
                        newDiv.addEventListener("click", function(evt){that.handleFilterClick(evt, aFilter, filtersDD)}, false);
                    }, this);
                }

                var renderedWidth = this.getComputedWidth(filtersDD);
                this.filters.style.width = "" + (parseInt((renderedWidth.substring(0, (renderedWidth.length - 2)))) + 20) + "px";
            }else{
                this.filters.style.display = "none";
            }
            /**
             * attach click event listeners to the addressbar dropdown arrows
             */
            var dropDownArrows = this.element.getElementsByClassName("dropdownArrow");
            for(var x=0; x<dropDownArrows.length;x++){
                dropDownArrows[x].addEventListener("click", function(evt){that.handleAddressDropdownArrowClick(evt);}, false);
            }

            this.iconView.addEventListener("click", this, false);
            this.treeView.addEventListener("click", this, false);
            this.element.addEventListener("drawTree", function(evt){that.handlePickerNavDrawTree(evt);}, false);
            this.element.addEventListener("refreshTreeSegment", function(evt){that.handlePickerNavRefreshTreeSegment(evt);}, false);
            this.resultsArea.addEventListener("click", function(evt){that.handleResultsAreaClick(evt);}, false);
            this.element.addEventListener("click", function(evt){that.handlePickerNavClick(evt);}, false);
            this.okButton.addEventListener("click", function(evt){that.handleOkButtonAction(evt);}, false);
            this.cancelButton.addEventListener("click", function(evt){that.handleCancelButtonAction(evt);}, false);

            this.element.addEventListener("keyup", function(evt){
                if(evt.keyCode == 27) {
                    if(that.application.ninja.filePickerController.pickerNavChoices !== null){
                        that.handleCancelButtonAction();
                    }
                }
            }, true);

            //ready to show picker now
            this.element.style.visibility = "visible";
            this.element.focus();
    	}
    },

    updateAddressBar:{
        writable: false,
        enumerable:true,
        value: function(folderUri){
            var addressBarEl = this.addressBarUri;
            if(addressBarEl){
                addressBarEl.value = folderUri;

                //update left drive selection
                
            }
        }
    },

    cleanupUri:{
        writable: false,
        enumerable:true,
        value: function(folderUri){
            folderUri = folderUri.replace(/^\s+|\s+$/g,"");  // strip any leading or trailing spaces
            //remove unnecessary / from end - for Win and Mac .... don't trim for the root
            if(((folderUri.charAt(folderUri.length - 1) === "/") || (folderUri.charAt(folderUri.length - 1) === "\\")) && (folderUri !== "/")){
                folderUri = folderUri.substring(0, (folderUri.length - 1));
                //console.log("*** new uri = "+ folderUri);
            }

            return folderUri;
        }
    },

    clearSelection:{
        writable: false,
        enumerable:true,
        value: function(folderUri){
            if((this.currentSelectedNode !== null) && (this.currentSelectedNode.classList.contains("selected"))){
                this.currentSelectedNode.classList.remove("selected");
            }
            this.currentSelectedNode = null;
            //disable OK
            if(!this.okButton.hasAttribute("disabled")){
                this.okButton.setAttribute("disabled", "true");
            }
        }
    },

    toggleDropdown:{
        writable: false,
        enumerable:true,
        value: function(dropdownArrowEl){
            var dropdownDiv = dropdownArrowEl.parentNode.getElementsByClassName("dropdown")[0];
            dropdownDiv.classList.toggle("hide");
        }
    },

    closeDropdowns:{
        writable:false,
        enumerable:true,
        value:function(clickedTarget){
            if(!clickedTarget.classList.contains("dropdownArrow")){//if not clicked on the drop down arrow itself
                var dropDowns = this.element.getElementsByClassName("dropdown");
                for(var x=0; x<dropDowns.length;x++){
                    if(!dropDowns[x].classList.contains("hide")){//if dropdown open
                        if(this.isOutside(dropDowns[x], clickedTarget)){
                            dropDowns[x].classList.add("hide");
                            //console.log("!!! closed DD: "+dropDowns[x].classList.toString());
                        }
                    }
                }
            }
        }
    },

    prepareAddressDropdownData:{
        writable:false,
        enumerable:true,
        value:function(uri){
            uri = this.cleanupUri(uri);
            var arr = [];
            var temp = new String(uri);
            while(temp.indexOf("/") != -1){

                if(""+temp === this.pickerModel.currentLogicalDrive){//stop at the logical drive
                    break;
                }

                temp = temp.substring(0, temp.lastIndexOf("/"));

                //populate dropdown irrespective of validity
//                if(!!this.application.ninja.filePickerController._directoryContentCache[temp]){//check if it is a valid location
//                    arr.push(temp);
//                }else{
//                    break;
//                }
                if(temp.length >0){
                    arr.push(temp);
                }else{//for unix root /
                    arr.push("/");
                }

            }
            //console.log(arr);
            return arr;
        }
    },

    renderTree:{
        writable:false,
        enumerable:true,
        value:function(element, uri){
            if(!!element){
                var tree = treeModule.Tree.create();
                tree.treeViewDataObject = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel);
                //console.log("renderTree() for "+ uri);
                //console.log(tree.treeViewDataObject);
                tree.element = element;
                tree.needsDraw = true;
            }
        }
    },

    updateIconView:{
        writable:false,
        enumerable:true,
        value:function(uri, fromCache){
            var status = true;
            var iconViewContainer = this.element.querySelector(".iconViewContainer");
            if((typeof fromCache === 'undefined') || (fromCache === true)){
            this.newContent = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel);
            }
            else{
                this.newContent = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel, false);
            }
            if(!!this.newContent && this.newContent.length > 0){
                //clear selection
                this.clearSelection();
                this.spanEl = iconViewContainer.querySelector(".noResults");
                if(!!this.spanEl){
                    this.spanEl.style.display = "none";
                }
                this.iconList.iconsViewDataObject = this.newContent;
            }else{
                this.iconList.iconsViewDataObject = [];
                this.spanEl = iconViewContainer.querySelector(".noResults");
                if(!!this.spanEl){
                    this.spanEl.style.display = "block";
                }else{
                    this.spanEl = document.createElement("span");
                    this.spanEl.className = "noResults";
                    this.spanEl.innerHTML = "no results";
                    this.spanEl.style.display = "block";
                    iconViewContainer.appendChild(this.spanEl);
                }
                status = false; //for no match
            }
            this.updateMetadata(uri);

            return status;
        }
    },

    updateTreeView:{
        writable:false,
        enumerable:true,
        value:function(uri, fromCache){
            var status = true;
            //need to draw every time since an expanded tree won't update with just bound data update
            var treeViewContainer =  this.element.querySelector(".treeViewContainer");
            //first clean up treeViewContainer
            while(treeViewContainer.hasChilden){
                treeViewContainer.removeChild(treeViewContainer.lastChild);
            }
            //now draw the unexpanded tree with the current uri data

            if(!!treeViewContainer){
                var data = [];
                if((typeof fromCache === 'undefined') || (fromCache === true)){
                    data = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel);
                }
                else{
                    data = this.application.ninja.filePickerController.prepareContentList(uri, this.pickerModel, false);
                }

                if(data.length > 0){

                    //clear selection
                    this.clearSelection();
                    this.spanEl = this.element.querySelector(".treeViewContainer").querySelector(".noResults");
                    if(!!this.spanEl){
                        this.spanEl.style.display = "none";
                    }

                    var tree = treeModule.Tree.create();
                    tree.treeViewDataObject = data;
                    tree.element = treeViewContainer;
                    tree.needsDraw = true;

                }else{

                    var treeUl = treeViewContainer.getElementsByTagName("ul")[0];
                    if(!!treeUl){
                        treeUl.style.display = "none";
                    }

                    this.spanEl = this.element.querySelector(".treeViewContainer").querySelector(".noResults");
                    if(!!this.spanEl){
                        this.spanEl.style.display = "block";
                    }else{
                        this.spanEl = document.createElement("span");
                        this.spanEl.className = "noResults";
                        this.spanEl.innerHTML = "no results";
                        this.spanEl.style.display = "block";
                        this.element.querySelector(".treeViewContainer").appendChild(this.spanEl);
                    }

                    status = false; //for no match
                }

                this.updateMetadata(uri);

                return status;
            }
        }
    },

    updateMetadata:{
        enumerable: false,
        writable:false,
        value:function(currentUri){
            var data = this.application.ninja.filePickerController._directoryContentCache[currentUri];
            var metadata = "";
            if(!!data){
                if(data.name !== ""){
                    metadata = "Name: "+data.name;
                }
                metadata = metadata + "<br />" + "Type: "+data.type;
                if(data.size){metadata = metadata + "<br />" + "Size: "+data.size+" bytes";}
                if(data.creationDate){metadata = metadata + "<br />" + "Creation date: "+ this.formatTimestamp(data.creationDate);}
                if(data.modifiedDate){metadata = metadata + "<br />" + "Modified date: "+ this.formatTimestamp(data.modifiedDate);}
            }
            this.element.getElementsByClassName("right-bottom")[0].innerHTML = metadata;
        }
    },

    isOutside:{
        enumerable:true,
        value:function(el, targetEl){
            var isOutside = true;
            if(el){
                var childElements = el.getElementsByTagName("*");//get a flat NodeList of all the child elements
                if(childElements != null){
                    for(var i=0; i< childElements.length; i++){
                        if(childElements[i] === targetEl){//targetEl matches with an element inside the menu
                            isOutside = false;
                            break;
                        }
                    }
                }
            }
            return isOutside;
        }
    },
    /**
     * convert timestamp to human readable form
     *
     * @param: timestamp - UTC milliseconds
     */
    formatTimestamp:{
        writable:false,
        enumerable: false,
        value: function(timestamp) {
            var aDate = new Date();
            timestamp = timestamp - (aDate.getTimezoneOffset()*60*1000);//convert from GMT to local timestamp
            aDate = new Date(timestamp);
            return aDate.toLocaleString();
        }
    },

    /**
     * Event Listners
     */

    addIdentifiers:{
        value: function(){
            this.element.identifier = "pickerNav";
            //this.addressGo.identifier = "addressGo";
            this.addressBarUri.identifier = "addressBarUri";
            this.refreshButton.identifier = "refreshButton";
            this.backArrow.identifier = "backArrow";
            this.forwardArrow.identifier = "forwardArrow";
            this.iconView.identifier = "iconView";
            this.treeView.identifier = "treeView";
            this.resultsArea.identifier = "resultsArea";
        }
    },

    handleTopLevelDirectoryClicks : {
        enumerable: true,
        writable: false,
        value : function(evt, dirObj){
                    this.currentURI = this.pickerModel.currentLogicalDrive = dirObj.uri;

                    var status = this.pickerViews()[this.selectedPickerView].call(this, dirObj.uri);//dynamically calls the update function of the current picker view

                    this.updateAddressBar(dirObj.uri);
                    this.pickerModel.currentRoot = dirObj.uri;

                    //populate history
                    this.pickerModel.storeHistory(dirObj.uri);
                    //disable forward button for explicit new urls
                    if(!this.forwardArrow.classList.contains("disable")){
                        this.forwardArrow.classList.add("disable");
                    }
                    //enable back button if required
                    if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){
                        this.backArrow.classList.remove("disable");
                    }

                    //dehighlight current selection and highlight new selection
                    var currentHighlighted = evt.target.parentNode.querySelector(".highlighted");
                    if(!!currentHighlighted){
                        currentHighlighted.classList.remove("highlighted");
                    }
                    if(!evt.target.classList.contains("highlighted")){
                        evt.target.classList.add("highlighted");
                    }

                    //enable ok for logical drive selections, when in directory selection mode
                    if(this.pickerModel.inFileMode === false){
                        this.okButton.removeAttribute("disabled");
                        //put into selectedItems..currently single selection is supported
                        this.selectedItems = [dirObj.uri];
                    }
                }
    },

    handlePickerNavOpenFolder: {
        value: function(evt){
                    this.currentURI = evt.folderUri;
                    var status = this.pickerViews()[this.selectedPickerView].call(this, evt.folderUri);//dynamically calls the update function of the current picker view

                    //update address-bar
                    this.updateAddressBar(evt.folderUri);

                    //populate history
                    this.pickerModel.storeHistory(evt.folderUri);

                    //disable forward button for explicit new urls
                    if(!this.forwardArrow.classList.contains("disable")){
                        this.forwardArrow.classList.add("disable");
                    }

                    //enable back button if required
                    if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){
                        this.backArrow.classList.remove("disable");
                    }

                    //for directory selection, selected url is the folder entered
                    if(!this.pickerModel.inFileMode ){
                        this.okButton.removeAttribute("disabled");
                        //put into selectedItems..currently single selection is supported
                        this.selectedItems = [evt.folderUri];
                    }

                }
    },


    handlePickerNavSelectedItem: {
        value:function(evt){
                    var uri = evt.uri;

                    //handle deselection of other icons for single selection
                    if((this.currentSelectedNode !== null) && (this.currentSelectedNode !== evt.target) && (this.currentSelectedNode.classList.contains("selected"))){
                        this.currentSelectedNode.classList.remove("selected");
                        this.currentSelectedNode = null;
                    }
                    //enable OK button if the selection is valid as per the picker mode
                    if((this.pickerModel.inFileMode && (this.application.ninja.filePickerController._directoryContentCache[uri].type === "file"))
                        || (!this.pickerModel.inFileMode && (this.application.ninja.filePickerController._directoryContentCache[uri].type === "directory"))){
                        this.okButton.removeAttribute("disabled");

                        //put into selectedItems..currently single selection is supported
                        this.selectedItems = [uri];

                        if(!evt.target.classList.contains("selected")){
                            evt.target.classList.add("selected");
                        }

                        this.currentSelectedNode = evt.target;

                    }else{


                        //test: highlight non-selectable icons too
                        if(!evt.target.classList.contains("selected")){
                            evt.target.classList.add("selected");
                        }
                        this.currentSelectedNode = evt.target;
                        //end- test


                        //disable OK
                        if(!this.okButton.hasAttribute("disabled")){
                            this.okButton.setAttribute("disabled", "true");
                        }
                    }
            }
    },

    handlePickerNavSelectedFile:{
        value: function(evt){
            var uri = evt.fileUri;

            //do selection if in file selection mode
            if(this.pickerModel.inFileMode && (this.application.ninja.filePickerController._directoryContentCache[uri].type === "file")){
                this.okButton.removeAttribute("disabled");
                //put into selectedItems..currently single selection is supported
                this.selectedItems = [uri];
                this.currentURI = uri.substring(0, uri.lastIndexOf("/"));
                this.handleOkButtonAction();
            }
        }
    },

    handlePickerNavShowMetadata: {
        value: function(evt){
                //update matadata only if nothing is already selected
                if(this.currentSelectedNode == null){
                    //console.log("handle showmetadata - true");
                    this.metadataSection.innerHTML = evt.metadata;
                }
        }
    },

    handlePickerNavUpdateMetadata:{
        value: function(evt){
                    this.metadataSection.innerHTML = evt.metadata;
                }
    },

    handleAddressGoClick :{
        value: function(evt){

                    if(this.addressBarUri.value !== ""){
                        var uri = this.addressBarUri.value;
                        uri = this.cleanupUri(uri);

                        this.currentURI = uri;
                        var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view

                        //populate history
                        this.pickerModel.storeHistory(uri);

                        //disable forward button for explicit new urls
                        if(!this.forwardArrow.classList.contains("disable")){
                            this.forwardArrow.classList.add("disable");
                        }

                        //enable back button if required
                        if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){
                            this.backArrow.classList.remove("disable");
                        }
                    }
                }
    },

    handleAddressBarUriKeydown:{
        value: function(evt){
                    if(evt.keyCode === 13 ){
                        var uri = this.addressBarUri.value;
                        uri = this.cleanupUri(uri);

                        this.currentURI = uri;

                        var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view

                        //populate history
                        this.pickerModel.storeHistory(uri);
                        //disable forward button for explicit new urls
                        if(!this.forwardArrow.classList.contains("disable")){
                            this.forwardArrow.classList.add("disable");
                        }
                        //enable back button if required
                        if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){
                            this.backArrow.classList.remove("disable");
                        }
                    }
              }
    },

    handleAddressBarUriKeyup:{
        value: function(evt){
            //disable ok if user enters an invalid uri
            if(!this.application.ninja.coreIoApi.isValidUri(this.addressBarUri.value)){
                //disable OK
                if(!this.okButton.hasAttribute("disabled")){
                    this.okButton.setAttribute("disabled", "true");
                }
            }else{
                this.okButton.removeAttribute("disabled");
                this.selectedItems = [this.addressBarUri.value];
            }
        }
    },

    handleRefreshButtonClick:{
        value:function(evt){
                var uri = this.addressBarUri.value;
                uri = this.cleanupUri(uri);

                var status = this.pickerViews()[this.selectedPickerView].call(this, uri, false);//dynamically calls the update function of the current picker view

            }
    },

    handleBackArrowClick :{
        value:function(evt){
                var uri = "";
                //console.log("*** backArrow: pointer ="+this.pickerModel.currentHistoryPointer);
                if(this.pickerModel.currentHistoryPointer >0){
                    uri = this.pickerModel._history[this.pickerModel.currentHistoryPointer -1];
                    //console.log("*** back uri= "+ uri);
                    //console.log(this.pickerModel._history);

                    this.currentURI = uri;
                    var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view

                    //update address-bar
                    this.updateAddressBar(uri);

                    this.pickerModel.currentHistoryPointer -= 1;

                    //disable back button if it is at the beginning
                    if((this.pickerModel.currentHistoryPointer === 0) && (!evt.target.classList.contains("disable"))){
                        evt.target.classList.add("disable");
                    }
                    //enable forward button if required
                    if((this.pickerModel.currentHistoryPointer < (this.pickerModel._history.length -1) && (this.forwardArrow.classList.contains("disable")))){
                        this.forwardArrow.classList.remove("disable");
                    }
                }
                //console.log("***new backArrow: pointer ="+this.pickerModel.currentHistoryPointer);
            }
    },

    handleForwardArrowClick: {
        value:function(evt){
                var uri = "";
                //console.log("*** forwardArrow: pointer ="+this.pickerModel.currentHistoryPointer);
                if(this.pickerModel.currentHistoryPointer < (this.pickerModel._history.length -1)){
                    uri = this.pickerModel._history[this.pickerModel.currentHistoryPointer + 1];
                    //console.log("*** forward uri= "+ uri);
                    //console.log(this.pickerModel._history);

                    this.currentURI = uri;
                    var status = this.pickerViews()[this.selectedPickerView].call(this, uri);//dynamically calls the update function of the current picker view

                    //update address-bar
                    this.updateAddressBar(uri);

                    this.pickerModel.currentHistoryPointer += 1;

                    //disable forward button if pointer is at the end
                    if((this.pickerModel.currentHistoryPointer === (this.pickerModel._history.length -1)) && (!evt.target.classList.contains("disable"))){
                        evt.target.classList.add("disable");
                    }

                    //enable back button if required
                    if((this.pickerModel.currentHistoryPointer > 0) && (this.backArrow.classList.contains("disable"))){
                        this.backArrow.classList.remove("disable");
                    }

                }
                //console.log("***new forwardArrow: pointer ="+this.pickerModel.currentHistoryPointer);
            }
    },

    handleOkButtonAction : {
        value: function(evt){
                    //console.log("$$$ File Picker : selected "+ this.selectedItems.toString());
                    var success = true;
                    if(!!this.pickerModel.callback && (this.selectedItems.length > 0)){//call the callback if it is available
                        try{
                            this.pickerModel.callback({"uri":this.selectedItems});
                        }catch(e){
                            success = false;
                            console.log("[Error] Failed to open "+ this.selectedItems.toString());
                            console.log(e.stack);
                        }
                    }else{//else send an event with the selected files
                        var pickerSelectionEvent = document.createEvent("Events");
                        pickerSelectionEvent.initEvent("pickerSelectionsDone", false, false);
                        pickerSelectionEvent.selectedItems = this.selectedItems;
                        this.eventManager.dispatchEvent(pickerSelectionEvent);
                    }

                    //store last opened/saved folder, and view after IO is successful
                    var dataStore = window.sessionStorage;
                    try {
                        if(this.pickerModel.pickerMode === "write"){
                            dataStore.setItem('lastSavedFolderURI', encodeURI(""+this.currentURI));
                        }
                        else if(this.pickerModel.inFileMode === true){
                            dataStore.setItem('lastOpenedFolderURI_fileSelection',encodeURI(""+this.currentURI));
                        }else if(this.pickerModel.inFileMode === false){
                            dataStore.setItem('lastOpenedFolderURI_folderSelection',encodeURI(""+this.currentURI));
                        }
                    }
                    catch(e){
                        if(e.code == 22){
                            dataStore.clear();
                        }
                    }

                    this.cleanup();//clear up any unnecessary memory

                    if(this.popup){
                        this.popup.hide();
                    }
                    //end - close dialog
              }
    },

    handleCancelButtonAction :{
        value:function(evt){
                //clean up memory
                this.cleanup();

                if(this.popup){
                    this.popup.hide();
                }

            }
    },

    handleFilterClick:{
        value: function(evt, aFilter, filtersDD){
                    this.pickerModel.currentFilter = aFilter;

                    this.pickerViews()[this.selectedPickerView].call(this, this.currentURI);//dynamically calls the update function of the current picker view

                    this.element.querySelector(".filters .filterVal").innerHTML = evt.target.innerHTML;
                    filtersDD.classList.toggle("hide");
                }
    },

    handleAddressDropdownArrowClick:{
        value: function(evt){
            var that = this;

            //populate dropdown dynamically for addressbar
            var addressbarDD = this.element.querySelector(".addressbar .dropdown");
            if((evt.target === this.element.querySelector(".addressbar .dropdownArrow")) && (addressbarDD.classList.contains("hide"))){//dropdown is closed

                //clear old dropdown contents
                while(addressbarDD.hasChildNodes()){
                    addressbarDD.removeChild(addressbarDD.lastChild);
                }

                var uriTrail = this.prepareAddressDropdownData(this.addressBarUri.value);
                if(uriTrail.length >0){
                    uriTrail.forEach(function(aUri){
                        var newDiv = document.createElement("div");
                        newDiv.innerHTML = aUri;
                        addressbarDD.appendChild(newDiv);
                        newDiv.addEventListener("click", function(evt){that.handleAddressTrailClick(evt, aUri, addressbarDD);}, false);
                    }, this);
                }
            }
            //open close dropdown
            this.toggleDropdown(evt.target);
        }
    },

    handleAddressTrailClick: {
        value: function(evt, aUri, addressbarDD){
                    this.currentURI = aUri;
                    var status = this.pickerViews()[this.selectedPickerView].call(this, aUri);//dynamically calls the update function of the current picker view

                    //populate history
                    this.pickerModel.storeHistory(aUri);
                    //disable forward button for explicit new urls
                    if(!this.forwardArrow.classList.contains("disable")){
                        this.forwardArrow.classList.add("disable");
                    }
                    //enable back button if required
                    if((this.pickerModel.currentHistoryPointer === 1) && this.backArrow.classList.contains("disable")){
                        this.backArrow.classList.remove("disable");
                    }
                    this.addressBarUri.value = evt.target.innerHTML;
                    addressbarDD.classList.toggle("hide");
                }
    },

    handleIconViewClick :{
        value:function(evt){

                this.selectedPickerView = "iconView";

                if(this.element.querySelector(".iconViewContainer").style.display === "none"){
                    //draw if icons list is not already drawn
                    if(this.iconsViewDrawnOnce === false){
                        this.iconList = iconsListModule.IconsList.create();
                        this.iconList.iconsViewDataObject = that.mainContentData;
                        this.iconList.element = that.iconViewContainer;
                        this.iconList.needsDraw = true;
                        this.iconsViewDrawnOnce = true;
                    }else{
                        this.pickerViews()[this.selectedPickerView].call(this, this.currentURI);
                    }
                    this.element.querySelector(".iconViewContainer").style.display = "block";
                }
                this.element.querySelector(".treeViewContainer").style.display = "none";

                //enable selection
                if(!evt.target.classList.contains("viewSelected")){
                    evt.target.classList.add("viewSelected")
                }
                if(this.treeView.classList.contains("viewSelected")){
                    this.treeView.classList.remove("viewSelected");
                }
            }
    },

    handleTreeViewClick : {
        value:function(evt){

                this.selectedPickerView = "treeView";

                if(this.element.querySelector(".treeViewContainer").style.display === "none"){

                    this.pickerViews()[this.selectedPickerView].call(this, this.currentURI);

                    this.element.querySelector(".treeViewContainer").style.display = "block";
                }
                this.element.querySelector(".iconViewContainer").style.display = "none";

                //enable selection
                if(!evt.target.classList.contains("viewSelected")){
                    evt.target.classList.add("viewSelected")
                }
                if(this.iconView.classList.contains("viewSelected")){
                    this.iconView.classList.remove("viewSelected");
                }

            }
    },

    handlePickerNavDrawTree:{
        value: function(evt){
                //toggle open or close for directory
                if(evt.uriType === "directory"){
                    this.renderTree(evt.subTreeContainer, evt.uri);
                }
            }
    },

    handlePickerNavRefreshTreeSegment:{
        value: function(evt){
//                if(this.application.ninja.filePickerController.checkIfStale(evt.uri)){
//                    //update tree segment if was stale
//                    evt.treeSegment.treeViewDataObject = this.application.ninja.filePickerController.prepareContentList(evt.uri, this.pickerModel, true, false);
//                }
            }
    },

    handleResultsAreaClick: {
        value:function(evt){
                //console.log("### clicked right-top");
                if((evt.target.querySelectorAll(".icon").length > 1)
                    || (evt.target.querySelectorAll(".atreeItem").length > 1)){//not clicked on an icon
                    //console.log("@@ clicked in empty area");
                    this.clearSelection();
                }
            }
    },

    handlePickerNavClick:{
        value: function(evt){
                //console.log("### clicked picker");
                this.closeDropdowns(evt.target);
            }
    },

    getComputedWidth:{
        value: function(element){
            var calculatedWidth = "0px";
            var orginalDisplay = element.style.display;
            var originalVisibility = element.style.visibility;
            element.style.display = "block";
            element.style.visibility = "hidden";
            calculatedWidth = window.getComputedStyle(element, null).getPropertyValue("width");
            element.style.display = orginalDisplay;
            element.style.visibility = originalVisibility;
            return calculatedWidth;
        }
    },

    cleanup:{
            writable:false,
            enumerable:true,
            value:function(){
                //clear memory - TODO:check for more memory leaks
                this.pickerModel = null;
                this.application.ninja.filePickerController._directoryContentCache = {};
                this.application.ninja.filePickerController.pickerNavChoices = null;
                //remove listeners
                this.element.removeEventListener("openFolder", this, false);//add icon double click event listener to reload iconList with new set of data
                this.element.removeEventListener("selectedItem", this, false);//for single selection only
                this.element.removeEventListener("showMetadata", this, false);//show metadata on hover of icon
                this.element.removeEventListener("updateMetadata", this, false);//show metadata on click of icon
                //this.addressGo.removeEventListener("click", this, false);
                this.addressBarUri.removeEventListener("keydown", this, false);
                this.refreshButton.removeEventListener("click", this, false);//refresh - gets from file system directly
                this.backArrow.removeEventListener("click", this, false);
                this.forwardArrow.removeEventListener("click", this, false);
                this.iconView.removeEventListener("click", this, false);
                this.treeView.removeEventListener("click", this, false);
                this.element.removeEventListener("drawTree", this, false);
                this.resultsArea.removeEventListener("click", this, false);
                this.element.removeEventListener("click", this, false);

            }
        }

});