/*
 * **************************Copyright Sense/Net****************************
 * Sense/Net 6.0 BETA 4.3
 * *************************************************************************
 * Sense/Net Enterprise Portal & ECMS 6.0 BETA 4.3
 * Copyright (C) 1999-2008, Sense/Net Ltd. 
 * 
 * See license.txt for licensing conditions.
 * 
 * You can contact Sense/Net:
 * www.sensenet.hu
 * info@sensenet.hu
 * H-1117 Budapest Infopark st 1., Hungary
 * **************************Copyright Sense/Net**************************** 
 */

Type.registerNamespace("ASPCode.net");

ASPCode.net._CookieManager = function(){
    
    ASPCode.net._CookieManager.initializeBase(this);
}
ASPCode.net._CookieManager.prototype = {
    setCookie: function(sName, sValue, oOptions){
        oOptions = oOptions ||
        {};
        var sExpires = '';
        if (oOptions.expires && (typeof oOptions.expires == 'number' || oOptions.expires.toGMTString)) {
            var date;
            if (typeof oOptions.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (oOptions.expires * 24 * 60 * 60 * 1000));
            }
            else {
                date = oOptions.expires;
            }
            sExpires = '; expires=' + date.toGMTString();
        }
        var sPath = oOptions.path ? '; path=' + oOptions.path : '';
        var sDomain = oOptions.domain ? '; domain=' + oOptions.domain : '';
        var sSecure = oOptions.secure ? '; secure=' + oOptions.secure : '';
        
        document.cookie = sName + '=' + sValue +
        sPath +
        sDomain +
        sSecure +
        sExpires;
        
        
        
    },
    deleteCookie: function(sName, oOptions){
        if (this.getCookie(sName)) {
            oOptions = oOptions ||
            {};
            var sPath = oOptions.path ? '; path=' + oOptions.path : '';
            var sDomain = oOptions.domain ? '; domain=' + oOptions.domain : '';
            
            document.cookie = sName + '=' + '' +
            sPath +
            sDomain +
            ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
        }
    },
    cookies: function(){
        //Return array - of string...
        if (document.cookie && document.cookie != '') {
            return document.cookie.split(';');
        }
        
    },
    getCookie: function(sName){
        var retValue = null;
        //Supports?
        if (document.cookie && document.cookie != '') {
            var cookieArray = document.cookie.split(';');
            for (var n = 0; n < cookieArray.length; n++) {
                var oneCookie = cookieArray[n].trim();
                if (oneCookie.startsWith(sName + '=')) {
                    retValue = decodeURIComponent(oneCookie.substring(sName.length + 1));
                    break;
                }
            }
        }
        return retValue;
    }
}


ASPCode.net._CookieManager.registerClass('ASPCode.net._CookieManager', Sys.Component);

ASPCode.net.CookieManager = new ASPCode.net._CookieManager();
Ext.namespace('SN.ContentExplorer');
Ext.FormViewport = Ext.extend(Ext.Container, {
    initComponent: function() {
        Ext.FormViewport.superclass.initComponent.call(this);
        document.getElementsByTagName('html')[0].className += ' x-viewport';
        this.el = Ext.get(document.forms[0]);
        this.el.setHeight = Ext.emptyFn;
        this.el.setWidth = Ext.emptyFn;
        this.el.setSize = Ext.emptyFn;
        this.el.dom.scroll = 'no';
        this.allowDomMove = false;
        this.autoWidth = true;
        this.autoHeight = true;
        Ext.EventManager.onWindowResize(this.fireResize, this);
        this.renderTo = this.el;
    },

    fireResize: function(w, h) {
        this.fireEvent('resize', this, w, h, w, h);
    }
});
Ext.reg('FormViewport', Ext.FormViewport);

Ext.data.Field = function(config) {
  if (typeof config == "string") {
    config = {
      name: config
    };
  }
  Ext.apply(this, config);

  if (!this.type) this.type = "auto";

  var st = Ext.data.SortTypes;
  // named sortTypes are supported, here we look them up
  if (typeof this.sortType == "string") this.sortType = st[this.sortType];

  // set default sortType for strings and dates
  if (!this.sortType) {
    switch (this.type) {
      case "string":
        this.sortType = st.asUCString;
        break;
      case "date":
        this.sortType = st.asDate;
        break;
      default:
        this.sortType = st.none;
    }
  }

  // define once
  var stripRe = /[\$,%]/g;
  var msdateRe = /\/Date\((\d+)[\+\-](\d+)\)\//; // MS JSON date format
  // prebuilt conversion function for this field, instead of
  // switching every time we're reading a value
  if (!this.convert) {
    var cv, dateFormat = this.dateFormat;
    switch (this.type) {
      case "":
      case "auto":
      case undefined:
        cv = function(v) {
          return v;
        };
        break;
      case "string":
        cv = function(v) {
          return (v === undefined || v === null) ? '' : String(v);
        };
        break;
      case "int":
        cv = function(v) {
          return v !== undefined && v !== null && v !== '' ? parseInt(String(v).replace(stripRe, ""), 10) : '';
        };
        break;
      case "float":
        cv = function(v) {
          return v !== undefined && v !== null && v !== '' ? parseFloat(String(v).replace(stripRe, ""), 10) : '';
        };
        break;
      case "bool":
      case "boolean":
        cv = function(v) {
          return v === true || v === "true" || v == 1;
        };
        break;
      case "date":
        cv = function(v) {
          if (!v) return '';
          if (Ext.isDate(v)) return v;
          if (v.match(msdateRe).length > 1) {
            // expects MS JSON dates of the form /Date(1069689066000)/
            return new Date(parseInt(v.replace(msdateRe, '$1')));
          }
          if (dateFormat) {
            if (dateFormat == "timestamp") {
              return new Date(v * 1000);
            }
            if (dateFormat == "time") {
              return new Date(parseInt(v, 10));
            }
            return Date.parseDate(v, dateFormat);
          }
          var parsed = Date.parse(v);
          return parsed ? new Date(parsed) : null;
        };
        break;

    }
    this.convert = cv;
  }
};
Ext.data.Field.prototype = {
  dateFormat: null,
  defaultValue: "",
  mapping: null,
  sortType: null,
  sortDir: "ASC"
};

// Register namespaces /////////////////////////////////////////

SN.ContentExplorer = {
  RootNodeId: '/Root',
  RootNodeText: 'Root',
  SR: {
  SelectionRequiredB4Upload: 'You have to select an item in the tree or in the grid before upload file into the Sense/Net Content Repository.',
  SelectionRequeireB4Delete: 'You have to select something in the tree or in the grid before delete a content from the Sense/Net Content Repository.',
    UploadHeaderText: 'Upload to {0}',
    VersionAndSecurityHeaderText: '{0} ({1})'
  },
  Templates: {
    NewContentGridRowTpl: '<div class="topic"><b>{0}</b><span class="author">{1}</span></div>',
    DialogGridTpl: '<div id="DialogGrid"></div>',
    CloseButtonTpl: '<div id="closeButton" class="snCloseButton"></div>'
  },
  initialConfiguration: {
    config: {
      componentList: 'Tree,Grid,Toolbar,Dialog',
      pathTextId: 'PathText',
      searchTextId: 'FullText',
      layoutConfig: {
        northPaneElementId: 'north',
        treePanelElementId: 'navPaneTree',
        searchPanelElementId: 'navPaneSearch',
        propertiesElementId: 'properties',
        dataSheetElementId: 'DataSheetUpdatePanel',
        versionSheetElementId: 'snVersionTab',
        securitySheetElementId: 'snSecurityTab'
      },

      gridFields: ['Id', 'Name', 'Path', 'Index', 'Size', 'ContentType', {
        name: 'CreationDate',
        type: 'date'
      }, 'CreatedBy', {
        name: 'ModificationDate',
        type: 'date'
      }, 'ModifiedBy', 'LockedBy', 'HasBinary', 'Index'],
      gridColumns: [{
        id: 'Name',
        header: 'Name',
        sortable: true,
        width: 200,
        dataIndex: 'Name',
        renderer: function(value, p, record) {
          /// Renders the name with an icon based upon the icon property of the actual content. (.substring(value.indexOf(" ") + 1, value.length))
          return String.format('<div class="snIconNodeGrid {1}">{0}</div>', value, record.json.iconCls);
        }
      }, {
        id: 'ModifyDate',
        header: 'Modification date',
        sortable: true,
        dataIndex: 'ModificationDate',

        width: 110
      }, {
        id: 'ModifiedBy',
        header: 'Modified by',
        sortable: true,
        width: 90,
        dataIndex: 'ModifiedBy'
      }, {
        id: 'LockedBy',
        header: 'Checked out to',
        sortable: true,
        width: 90,
        dataIndex: 'LockedBy'
      }, {
        id: 'Download',
        header: '',
        width: 30,
        renderer: function(value, p, record) {
          /// Renders download link if the record stores a node which has binary propery.
          var iconClass = "snIconSmall_Download";
          var j = record.json;
          var result = '';
          if (j && j.HasBinary) {
            result = String.format('<a href="{1}" target="_blank" style="display:block;" class="snIconSmall {0}"></a>', iconClass, record.json.Path);
          }
          return result;
        }
      }],

      urlList: {
        treeLoaderUrl: '/ContentStore.svc/GetFeed2?onlyFolders=true&start=0&limit=0',
        gridLoaderUrl: '/ContentStore.svc/GetItem2?node={0}&onlyFileChildren=false',
        copyUrl: '/ContentStore.svc/Copy?node={0}&target={1}',
        moveUrl: '/ContentStore.svc/Move?node={0}&target={1}',
        deleteUrl: '/ContentStore.svc/Delete?node={0}',
        getContentTypeNamesUrl: '/ContentStore.svc/GetContentTypes',
        searchUrl: '/ContentStore.svc/Search?expr={0}'
      }
    }
  }
};
Ext.namespace('SN.ContentPicker');
Ext.namespace('SN.GUI');
Ext.BLANK_IMAGE_URL = '/Root/System/Common/img/s.gif';

Ext.BLANK_IMAGE_URL = '/JS/ext30/resources/images/default/s.gif';

SN.GUI = {
  CalculatePosition: function(htmlElement, overall, disableTricks) {
    var result = new Object();
    var log = '';
    result.top = 0;
    result.left = 0;
    result.log = new Array();
    var i = 0;
    var j = (disableTricks ? -1 : 0);
    if (!htmlElement.tagName) htmlElement = htmlElement.parentNode;
    while (htmlElement != null && htmlElement != document) {
      if (htmlElement.style.position != "absolute") {
        result.top += htmlElement.offsetTop / 1;
        if (i != j || htmlElement.offsetLeft < ((htmlElement.offsetWidth / 2) - 10)) {
          result.left += htmlElement.offsetLeft / 1;
        }
      }
      result.log[result.log.length] = {
        tagName: htmlElement.tagName,
        id: htmlElement.id,
        position: htmlElement.style.position,
        offsetLeft: htmlElement.offsetLeft,
        offsetTop: htmlElement.offsetTop,
        offsetWidth: htmlElement.offsetWidth,
        resultLeft: result.left,
        resultTop: result.top
      };
      if (htmlElement.tagName == 'MARQUEE' && htmlElement.direction == 'left') result.left -= htmlElement.clientWidth;
      if (htmlElement.tagName == 'MARQUEE' && htmlElement.direction == 'up') result.top -= htmlElement.clientHeight;
      try {
        htmlElement = htmlElement.offsetParent;
      } catch (ex) {
        htmlElement = null;
      }
      if (htmlElement == null || htmlElement == document) return result;
      i++;
    }
    return result;
  },
  ClosePortletMenu: function(e, o) {
    tools = o.parentNode.parentNode;
    o = tools.verbs;
    var closeClass = ' snPtVerbsClosed';
    if (o.className.indexOf(closeClass) != -1) return;
    o.className += closeClass;
    tools.style.display = 'none';
    this.StopPropagation(e);
  },
  GetStyle: function(o, name) {
    var value = "";
    if (document.defaultView && document.defaultView.getComputedStyle) {
      return document.defaultView.getComputedStyle(o, "").getPropertyValue(name);
    }
    if (o.currentStyle) {
      name = name.replace('/\-(\w)/g', function(strMatch, p1) { return p1.toUpperCase(); });
      return o.currentStyle[name];
    }
  },
  OpenPortletMenu: function(o) {
    var closeClass = ' snPtVerbsClosed';
    o.className = o.className.replace(closeClass, '');
    var tools = o.firstChild;
    while (tools && !tools.tagName) tools = tools.nextSibling;
    if (tools == null) {
      tools = o.tools;
      tools.style.display = 'block';
      return;
    }
    var pos = this.CalculatePosition(tools, true);
    var form = document.getElementById('aspnetForm');
    form.appendChild(tools);
    tools.style.left = pos.left + 'px';
    tools.style.top = pos.top + 'px';
    tools.verbs = o;
    o.tools = tools;
  },
  StopPropagation: function(e) {
    if (Ext.isIE) {
      e.returnValue = false;
      e.cancelBubble = true;
    } else {
      try {
        e.preventDefault();
        e.stopPropagation();
      } catch (ex) { }
    }
  },
  ToggleFieldset: function(o) {
    var closeClass = ' sn-fieldset-close';
    do {
      var tmp = o.className.split(' ');
      if (tmp[0] != 'sn-fieldset') o = o.parentNode;
    } while (tmp[0] != 'sn-fieldset');
    if (o.className.indexOf(closeClass) == -1) {
      o.className += closeClass;
    } else {
      o.className = o.className.replace(closeClass, '');
    }
  }
}

Ext.onReady(function() {
  function customize(a, types) {
    var isIE = window.ActiveXObject ? true : false;
    var t = ' ' + types + ' ';
    for (var i = 0; i < a.length; i++) {
      if (types && t.indexOf(' ' + a[i].type + ' ') == -1) continue;
      if (a[i].className == 'x-btn-text') continue;
      var p = a[i];
      do {
        p = p.parentNode;
      } while (p != null && (p.className == null || p.className.indexOf('x-window') == -1));
      if (p == null) continue;

      var table = Ext.DomHelper.insertBefore(a[i], {
        tag: 'table',
        id: a[i].id,
        cellSpacing: 0,
        cellPadding: 0,
        border: 0,
        cls: 'x-btn-wrap x-btn',
        html: '<tbody><tr><td class="x-btn-left"><i> </i></td><td class="x-btn-center"><em unselectable="on"></em></td><td class="x-btn-right"><i> </i></td></tr></tbody>'
      });
      table.style.width = 'auto';
      table.style.display = 'inline';
      var em = table.getElementsByTagName('EM');
      a[i].id = a[i].id + 'Control';
      a[i].className = 'x-btn-text';
      if (a[i].style.display == 'none') {
        a[i].style.display = 'inherited';
        table.style.display = 'none';
      }
      em[0].appendChild(a[i]);
    }
  }
  customize(document.getElementsByTagName('INPUT'), 'button submit');
  customize(document.getElementsByTagName('BUTTON'));
});

  

Ext.ux.Hashtable = function()
{
    this.clear = hashtable_clear;
    this.containsKey = hashtable_containsKey;
    this.containsValue = hashtable_containsValue;
    this.get = hashtable_get;
    this.isEmpty = hashtable_isEmpty;
    this.keys = hashtable_keys;
    this.put = hashtable_put;
    this.remove = hashtable_remove;
    this.size = hashtable_size;
    this.toString = hashtable_toString;
    this.values = hashtable_values;
    
    var items = {};
    var count = 0;
    //	serve per confrontare che non sia una proprieta nativa
	var testObject = {};


    

    function hashtable_clear(){
        items = {};
        count = 0;
    }

    function hashtable_containsKey(key){
        if (testObject[key]) {
			return false;
	    }
		return (items[key] != null);
    }

    function hashtable_containsValue(value){
        var a = getValueArray();
        for (var htIndex = 0; htIndex < a.length; htIndex++) {
            if (a[htIndex] == value) {
                return true;
            }
        }
        return false;     
    }

    function hashtable_get(key){
        if(key in items){
			return items[key];	//	object
		}
		return undefined;
    }

    function hashtable_isEmpty(){
        return (count == 0);
    }

    function hashtable_keys(){
        return getKeyArray();
    }

    function hashtable_put(key, value){
        if (key == null || value == null) {
            throw "NullPointerException {" + key + "},{" + value + "}";
        }else{
            var alreadyExists = (key in items);
		    items[key] = value;
		    if(!alreadyExists){
			    count++;
		    }
        }
    }

    function hashtable_remove(key){
		if(key in items && !testObject[key]){
			delete items[key];
			count--;
			return true;
		}
		return false;
    }

    function hashtable_size(){
       return count;
    }

    function hashtable_toString(){
        var result = '';
        var arrKeys = getKeyArray();
        for (var i = 0; i < arrKeys.length; i++)
        {     
            if (TI.Util.isNullOrUndefined(items[arrKeys[i]]))
                result += "{" + arrKeys[i] + "},{" + items[arrKeys[i]] + "}\n";  
        }
        return result;
    }

    function hashtable_values(){
        return getValueArray();
    }
    
    function getValueArray() {
        var a = [];
        for(var p in items){
		    if(!testObject[p]){
			    a.push(items[p]);
		    }
	    }
	    return a;
    }
    function getKeyArray() {
        var a = [];
        for(var p in items){
		    if(!testObject[p]){
			    a.push(p);
		    }
	    }
	    return a;
    }
}


SN.ContentPicker.Application = function() {
  var button = null;
  var target = null;
  var dialog = null;
  var settings = null;
  var layoutBuilder;
  var context;

  var layoutLoaded = function(res) {
    dialog = res.dialog;
    context = res.context;
    dialog.show(button, setRootNode);
  }

  var okButtonHandler = function() {
    var sel = context.GetSelectedItems();
    if (typeof target == 'function') {
      target.call(this, sel);
    } else if (settings.singleSelectMode.toLowerCase() == 'true') {
      target.dom.value = sel;
    } else {
      if (target.dom.value != '') target.dom.value += ';';
      target.dom.value += sel;
    }
    dialog.hide();
  }

  var cancelButtonHandler = function() {
    dialog.hide();
  }

  var setRootNode = function() {
    if (typeof target != 'object' || target == null) return;
    context.ExpandTree(target.dom.value);
  }

  var buildLayout = function(args) {
    if (typeof args === 'undefined') args = {};
    args.okButtonHandler = okButtonHandler;
    args.cancelButtonHandler = cancelButtonHandler;
    layoutBuilder = SN.GUI.LayoutBuilder;
    layoutBuilder.BuildViewPort('contentpicker', layoutLoaded, args);
  }

  var showDialog = function(args) {
    if (!dialog) {
      buildLayout(args);
    } else {
      if (args.rootFolderPath && args.rootFolderPath.indexOf('/') != -1) context.Tree.Reload(args.rootFolderPath);
      context.Grid.Instance().getSelectionModel().singleSelect = (args != null && args.singleSelectMode != null ? args.singleSelectMode === 'True' : false);
      dialog.show(button, setRootNode);
    }
  }

  return {
    Initialize: function() { },
    OpenWindow: function(args) {

      // IE7 hasLayout hack
      document.body.parentNode.style.position = 'relative';
      document.body.parentNode.style.zoom = '1';

      if (!args) args = {};
      settings = args;
      target = (args.textElementId != null ? Ext.get(args.textElementId) : args.callback);
      if (args.buttonId == null) button = Ext.get(args.buttonId);
      showDialog(args);
    }
  }
} ();
SN.ContentExplorer.Actions = function() {

  var addCloseButton = function() {
    var closeButtonTemplate = new Ext.XTemplate(SN.ContentExplorer.Templates.CloseButtonTpl);
    closeButtonTemplate.overwrite(Ext.fly('DialogButtonsTemplate').dom, {});
    var el = Ext.fly('closeButton');
    var components = SN.GUI.Components.Current;
    var dialog = components.GetInstance('Dialog', true);
    var closeBtn = new Ext.Button({
      applyTo: 'closeButton',
      text: 'Close',
      id: 'CloseButton',
      handler: function() {
        dialog.hide();
        components['Grid'].Reload();
      }
    });
  }

  var uploadPageLoaded = function(sender, args) {
    SN.GUI.Components.Current.GetInstance('Dialog').show();
    Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(uploadPageLoaded);
  };

  return {
    DeleteHandler: function(toolbarItem, event) {
      var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
      var components = SN.GUI.Components.Current;
      var ctl = 'ForcePostBackButton', eventArgs = 'Toolbar;' + toolbarItem.itemId, prm = Sys.WebForms.PageRequestManager.getInstance();

      var selection = components.GetSelectionType();
      if (selection == null) {
        Ext.MessageBox.alert('Status', '');
        return;
      }

      var component = components.GetInstance(selection);
      var messageFormat = "Are you sure you want to delete '{0}' content(s)?";
      var selectedNode, msg, i;

      switch (selection) {
        case 'Grid':
          eventArgs += ';Grid;' + component.selModel.getSelected().json.Id;
          msg = String.format(messageFormat, components.Grid.SelectionText());
          break;
        case 'Tree':
          selectedNode = component.getSelectionModel().selNode;
          eventArgs += ';Tree;' + selectedNode.id;
          msg = String.format(messageFormat, selectedNode.attributes.Path);
          break;
      }

      components.RemoveComponent('DialogGrid');

      Ext.MessageBox.confirm('Confirmation', msg, function(btn, text) {
        if (btn == 'yes') {
          var selectedItemsCount = 1, i = 0;
          var successdeleteHandler = function(a, b) {
            i++;
            if (i == selectedItemsCount) {
              Ext.MessageBox.hide();
              var t = SN.GUI.Components.Current.Tree;
              var g = SN.GUI.Components.Current.Grid;
              var node = t.Instance().selModel.selNode;
              t.Reload();
              g.LoadNode(node.attributes.id);
              node.ui.elNode.click()
            };
          };
          var failuredeleteHandler = function(response, request) {
            Ext.MessageBox.hide();

            //
            // need to use a workaround because of the missing concept of client-side exception handling
            //
            var responseText = response.responseText;
            var i = responseText.indexOf("Access denied");
            var minw = 900;
            var maxw = 1028;
            if (i != -1) {
              responseText = "You don't have sufficient permissions to delete this content.";
              minw = 300;
              maxw = 600;
            }
            Ext.MessageBox.show({
              title: 'Error',
              msg: responseText,
              buttons: Ext.MessageBox.OK,
              icon: Ext.MessageBox.ERROR,
              minWidth: minw,
              maxWidth: maxw
            });
          };
          var deleteRow = function(record, index, allItems) {
            var requestConfig = {
              url: String.format(urlList.deleteUrl, record.json.id),
              method: 'GET',
              success: successdeleteHandler,
              failure: failuredeleteHandler
            };
            Ext.Ajax.request(requestConfig);
          };

          var showMessageBox = function(text, multiple) {
            Ext.MessageBox.show({
              msg: String.format('Deleting {0} item{1}, please wait...', text, (multiple ? '(s)' : '')),
              progressText: 'Deleting...',
              width: 400,
              wait: true
            });
          }

          switch (selection) {
            case 'Grid':
              selectedTreeNode = component.selModel.selNode;
              selections = component.selModel.selections;
              i = 0;
              showMessageBox(selections.getCount(), true);
              Ext.each(selections.items, deleteRow);
              break;
            case 'Tree':
              var node = component.selModel.selNode;
              selectedTreeNode = node.attributes.ParentId;
              showMessageBox(node.attributes.Path, false);
              var successDeleteTreeNodeHandler = function(a, b) {
                Ext.MessageBox.hide();
                components.Grid.LoadNode(component.selModel.selNode.parentNode.attributes.id);
                var p = node.parentNode;
                p.reload();
                p.select();
              };
              var failureDeleteTreeNodeHandler = function(response, request) {
                Ext.MessageBox.hide();
                Ext.MessageBox.show({
                  title: 'Error',
                  msg: response.responseText,
                  buttons: Ext.MessageBox.OK,
                  icon: Ext.MessageBox.ERROR
                });
              };
              var requestConfig = {
                url: String.format(urlList.deleteUrl, component.selModel.selNode.attributes.id),
                method: 'GET',
                success: successDeleteTreeNodeHandler,
                failure: failureDeleteTreeNodeHandler
              };
              Ext.Ajax.request(requestConfig);
              break;
          }
        }
      });
    },
    UploadHandler: function(toolbarItem, event) {
      var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
      var components = SN.GUI.Components.Current;
      var selectedPath = null, ctl = 'ForcePostBackButton', eventArgs = 'Toolbar;' + toolbarItem.itemId, prm = Sys.WebForms.PageRequestManager.getInstance();
      var selection = components.GetSelectionType();
      if (selection == null) {
        Ext.MessageBox.alert('Status', SN.ContentExplorer.SR.SelectionRequired);
        return;
      }
      var tree = components.Tree.Instance();
      selectedPath = tree.getSelectionModel().selNode.attributes.Path;
      eventArgs += ';Tree;' + tree.getSelectionModel().selNode.id;

      components.RemoveUnnecessaryElements();

      Ext.fly('NewCtdButton').dom.style.display = 'none';

      var dialogHeader = Ext.fly('dialogHeaderTitle');
      if (dialogHeader) dialogHeader.dom.innerHTML = String.format(SN.ContentExplorer.SR.UploadHeaderText, selectedPath);
      var commandTo = Ext.fly('commandTo');
      if (commandTo) commandTo.dom.innerHTML = '';
      var dialog = components.GetInstance('Dialog', true);
      dialog.setTitle(toolbarItem.text);
      addCloseButton();
      prm.add_pageLoaded(uploadPageLoaded);
      prm._doPostBack(ctl, eventArgs);
    },
    NewContentHandler: function(toolbarItem, event) {
      var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
      var components = SN.GUI.Components.Current;
      components.SetSelectedControl('Tree');

      var newTemplate = new Ext.XTemplate(SN.ContentExplorer.Templates.DialogGridTpl);
      newTemplate.overwrite(Ext.fly('DialogTemplate').dom, {});

      //      if (selection == 'Grid') {
      //        var grid = components.GetInstance('Grid');
      //        var parentId = grid.selModel.getSelected().json.ParentId;
      //        var selectedNodeIdHidden = Ext.fly('SelectedNodeIdHidden');
      //        if (typeof (selectedNodeIdHidden) !== 'undefined') selectedNodeIdHidden.dom.value = parentId;
      //      }

      var dup = Ext.get('DialogUpdatePanel');
      var dg = dup.dom.firstChild;
      if (dg != null && dg.tagName == '') dg = dg.nextSibling;
      if (dg == null || dg.id !== 'DialogGrid') components.RemoveAllChildNodes('DialogUpdatePanel');
      components.RemoveAllChildNodes('DialogButtonsTemplate');

      Ext.fly('NewCtdButton').dom.style.display = 'inline';
      var h = Ext.fly('dialogHeaderTitle');
      if (h) h.dom.innerHTML = 'Select new content type';

      var dialog = components.GetInstance('Dialog', true);
      dialog.setSize(600, 500);
      dialog.setTitle(toolbarItem.text);
      dialog.show();

      var formatTitle = function(value, p, record) {
        return String.format(SN.ContentExplorer.Templates.NewContentGridRowTpl, value, record.data.Name);
      };

      dialogGrid = components.CreateComponent('Grid', 'Dialog');

    },
    CopyHandler: function(toolbarItem, event) {
      var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
      var components = SN.GUI.Components.Current;

      var copyTemplate = new Ext.XTemplate('<div id="commandHeader"></div>', '<div id="commandTo"></div>', '<div id="DialogTree"></div>');
      var copyButtonTemplates = new Ext.XTemplate('<div id="copyButton" class="snCopyButtonPlace"></div>', '<div id="cancelButton" class="snCancelButtonPlace"></div>');

      copyTemplate.overwrite(Ext.fly('DialogTemplate').dom, {});
      copyButtonTemplates.overwrite(Ext.fly('DialogButtonsTemplate').dom, {});

      var selection = SN.GUI.Components.Current.GetSelectionType();
      if (!selection) {
        Ext.MessageBox.alert('Status', 'You have to select something in the tree or in the grid before deleting a content from the Sense/Net Content Repository.');
        return;
      }

      components.RemoveAllChildNodes('DialogUpdatePanel');
      components.RemoveComponent('DialogGrid');

      Ext.fly('NewCtdButton').dom.style.display = 'none';
      var dialog = components.GetInstance('Dialog', true);
      dialog.setTitle(toolbarItem.text);

      var dialogTree = new Ext.tree.TreePanel({
        id: 'DialogTreePanel',
        el: 'DialogUpdatePanel',
        autoWidth: true,
        //autoHeight: true,
        height: 290,
        animate: true,
        autoScroll: true,
        loader: new Ext.tree.TreeLoader({
          requestMethod: 'GET',
          dataUrl: urlList.treeLoaderUrl
        }),
        enableDD: false
      });

      var treeSorter = new Ext.tree.TreeSorter(dialogTree, {
        folderSort: true,
        dir: 'asc'

      });

      var root = components.Tree.AsyncTreeNode();
      dialogTree.setRootNode(root);
      dialogTree.render();
      dialogTree.getSelectionModel().on('selectionchange', function(selModel, node) {
        components.UpdateDialogHeader(node, "Copy '{0}' content to...");
      });

      root.expand(false, false);
      root.select();


      components.UpdateDialogHeader(null, "Copy '{0}' content to...");

      var copyButtonHandler = function() {
        var i = 0, selectedItemsCount = 0;
        var successCopyHandler = function(a, b) {
          i++;
          if (i == selectedItemsCount) {
            Ext.MessageBox.hide();
            dialog.hide();
          };
        };
        var failureCopyHandler = function(response, request) {
          Ext.MessageBox.hide();
          //var text = String.format('{0} - {1}', response.status, response.statusText);
          Ext.MessageBox.show({
            title: 'Error',
            msg: response.responseText,
            buttons: Ext.MessageBox.OK,
            icon: Ext.MessageBox.ERROR
          });
        };
        var copyRow = function(record, index, allItems) {
          var requestConfig = {
            url: String.format(urlList.copyUrl, record.json.id, dialogTree.selModel.selNode.attributes.id),
            method: 'GET',
            success: successCopyHandler,
            failure: failureCopyHandler
          };
          Ext.Ajax.request(requestConfig);
        };

        var copyFromGrid = function() {
          var grid = SN.GUI.Components.Current.GetInstance('Grid');
          selectedItemsCount = grid.selModel.selections.getCount();
          i = 0;

          Ext.MessageBox.show({
            msg: String.format('Copying {0} item(s), please wait...', selectedItemsCount),
            progressText: 'Copying...',
            width: 400,
            wait: true
          });
          Ext.each(grid.selModel.selections.items, copyRow);
        };

        var copyFromTree = function() {
          Ext.MessageBox.show({
            msg: String.format('Copying {0} item, please wait...', SN.GUI.Components.Current.GetInstance('Tree').selModel.selNode.attributes.Path),
            progressText: 'Copying...',
            width: 400,
            wait: true
          });

          var successTreecopyHandler = function(a, b) {
            var grid = SN.GUI.Components.Current.GetInstance('Grid');
            var dialog = SN.GUI.Components.Current.GetInstance('Dialog', true);
            var tree = SN.GUI.Components.Current.GetInstance('Tree');
            Ext.MessageBox.hide();
            dialog.hide();
            grid.store.proxy.conn.url = String.format(urlList.gridLoaderUrl, tree.selModel.selNode.parentNode.attributes.id);
            grid.store.load();
            //                        grid.store.load({
            //                            params: {

            //                                start: 0,
            //                                limit: 25
            //                            }
            //                        });
          };

          var failureTreecopyHandler = function(response, request) {
            Ext.MessageBox.hide();
            //var text = String.format('{0} - {1}', response.status, response.statusText);
            Ext.MessageBox.show({
              title: 'Error',
              msg: response.responseText,
              buttons: Ext.MessageBox.OK,
              icon: Ext.MessageBox.ERROR
            });
          };

          var requestConfig = {
            url: String.format(urlList.copyUrl, SN.GUI.Components.Current.GetInstance('Tree').selModel.selNode.attributes.id, dialogTree.selModel.selNode.attributes.id),
            method: 'GET',
            success: successTreecopyHandler,
            failure: failureTreecopyHandler
          };
          Ext.Ajax.request(requestConfig);
        };

        switch (selection) {
          case 'Grid':
            copyFromGrid();
            break;
          case 'Tree':
            copyFromTree();
            break;
        }
      };

      var addDialogButtons = function() {
        var el = Ext.fly('copyButton');
        var copyBtn = new Ext.Button({
          applyTo: 'copyButton',
          text: 'Copy',
          id: 'CopyButton',
          handler: copyButtonHandler
        });
        var cancelBtn = new Ext.Button({
          applyTo: 'cancelButton',
          text: 'Close',
          id: 'CloseDialogButton',
          handler: function() {
            dialog.hide();
          }
        });

      }

      addDialogButtons();

      dialog.setSize(600, 500);
      dialog.show();
    },
    MoveHandler: function(toolbarItem, event) {
      var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
      var components = SN.GUI.Components.Current;

      var copyTemplate = new Ext.XTemplate('<div id="commandHeader"></div>', '<div id="commandTo"></div>', '<div id="DialogTree"></div>');
      var copyButtonTemplates = new Ext.XTemplate('<div id="moveButton"></div>', '<div id="cancelButton"></div>');

      copyTemplate.overwrite(Ext.fly('DialogTemplate').dom, {});
      copyButtonTemplates.overwrite(Ext.fly('DialogButtonsTemplate').dom, {});

      var selection = SN.GUI.Components.Current.GetSelectionType();
      if (!selection) {
        Ext.MessageBox.alert('Status', 'You have to select something in the tree or in the grid before deleting a content from the Sense/Net Content Repository.');
        return;
      }

      components.RemoveAllChildNodes('DialogUpdatePanel');
      components.RemoveComponent('DialogGrid');
      Ext.fly('NewCtdButton').dom.style.display = 'none';
      var dialog = components.GetInstance('Dialog', true);
      dialog.setTitle(toolbarItem.text);

      var dialogTree = new Ext.tree.TreePanel({
        id: 'DialogTreePanel',
        el: 'DialogUpdatePanel',
        autoWidth: true,
        height: 290,
        animate: true,
        autoScroll: true,
        loader: new Ext.tree.TreeLoader({
          requestMethod: 'GET',
          dataUrl: urlList.treeLoaderUrl
        }),
        enableDD: false
      });

      var treeSorter = new Ext.tree.TreeSorter(dialogTree, {
        folderSort: true,
        dir: 'asc'

      });

      var root = components.Tree.AsyncTreeNode();
      dialogTree.setRootNode(root);
      dialogTree.render();


      dialogTree.getSelectionModel().on('selectionchange', function(selModel, node) {
        components.UpdateDialogHeader(node, "Move '{0}' content to...");
        // get the Id-s
        var text;
        var selection = components.GetSelectionType();
        if (!selection)
          return;

        var selectedNodeParentId;
        var currentNodeParentId;
        var component = components.GetInstance(selection);

        var SetMoveButtonState = function(selectionParentId, currentSelModel) {
          if (currentSelModel === null)
            return; // or drop bomb:)
          var s = selModel.selNode;
          if (s && s.attributes.Name !== "/Root") {
            var currentNodeId = s.attributes.Id;
            var moveButton = Ext.getCmp("MoveButton");
            if (selectionParentId === currentNodeId)
              moveButton.disable();
            else
              moveButton.enable();
          }
        }

        switch (selection) {
          case 'Grid':
            try {
              SetMoveButtonState(component.getSelectionModel().selections.items[0].json.ParentId, selModel);
            } catch (exc) {
              alert('Untested issue has been occured, please debug what caused the object-reference exception!' + exc);
            }
            break;
          case 'Tree':
            try {
              SetMoveButtonState(component.getSelectionModel().selNode.attributes.ParentId, selModel);
            } catch (exc) {
              alert('Untested issue has been occured, please debug what caused the object-reference exception!' + exc);
            }
            break;
        }

      });

      root.expand(false, false);
      root.select();

      components.UpdateDialogHeader(null, "Move '{0}' content to...");



      var moveButtonHandler = function() {
        var selectedTreeNode = null, selectedItemsCount = 0;

        var successMoveHandler = function(a, b) {
          i++;
          if (i == selectedItemsCount) {
            Ext.MessageBox.hide();
            //var selectedNode = dialogTree.selModel.selNode;
            dialog.hide();
          };
        };
        var failureMoveHandler = function(response, request) {
          Ext.MessageBox.hide();
          //var text = String.format('{0} - {1}', response.status, response.statusText);
          Ext.MessageBox.show({
            title: 'Error',
            msg: response.responseText,
            buttons: Ext.MessageBox.OK,
            icon: Ext.MessageBox.ERROR
          });
        };
        var moveRow = function(record, index, allItems) {
          var requestConfig = {
            url: String.format(urlList.moveUrl, record.json.id, dialogTree.selModel.selNode.attributes.id),
            method: 'GET',
            success: successMoveHandler,
            failure: failureMoveHandler
          };
          Ext.Ajax.request(requestConfig);
        };
        var moveFromGrid = function() {
          var grid = SN.GUI.Components.Current.GetInstance('Grid');
          selectedItemsCount = grid.selModel.selections.getCount();
          i = 0;
          Ext.MessageBox.show({
            msg: String.format('Moving {0} item(s), please wait...', selectedItemsCount),
            progressText: 'Moving...',
            width: 400,
            wait: true
          });

          Ext.each(grid.selModel.selections.items, moveRow);
        };

        var moveFromTree = function() {
          //selectedTreeNode = tree.selModel.selNode.attributes.ParentId; // ????
          var tree = SN.GUI.Components.Current.GetInstance('Tree');
          Ext.MessageBox.show({
            msg: String.format('Moving {0} item, please wait...', tree.selModel.selNode.attributes.Path),
            progressText: 'Moving...',
            width: 400,
            wait: true
          });

          var successTreeMoveHandler = function(a, b) {
            var grid = SN.GUI.Components.Current.GetInstance('Grid');
            var dialog = SN.GUI.Components.Current.GetInstance('Dialog', true);
            var tree = SN.GUI.Components.Current.GetInstance('Tree');
            Ext.MessageBox.hide();

            grid.store.proxy.conn.url = String.format(urlList.gridLoaderUrl, tree.selModel.selNode.parentNode.attributes.id);
            grid.store.load({
              requestMethod: 'GET'
            });

            var p = tree.selModel.selNode.parentNode;
            var delNode = tree.selModel.selNode;
            tree.selModel.selNode.parentNode.removeChild(delNode);


            try {
              onTreeSelectionChange(tree.selModel, p);
              p.select();
              p.reload();
            } catch (e) {
              // when moving a Site with page nodes under the /Root: a this.getOwnerTree() is null but it does not affect the move process.
              // timing error.
            }




            dialog.hide();
          };
          var failureTreeMoveHandler = function(response, request) {
            Ext.MessageBox.hide();
            //var text = String.format('{0} - {1}', response.status, response.statusText);
            Ext.MessageBox.show({
              title: 'Error',
              msg: response.responseText,
              buttons: Ext.MessageBox.OK,
              icon: Ext.MessageBox.ERROR
            });
          };

          var requestConfig = {
            url: String.format(urlList.moveUrl, tree.selModel.selNode.attributes.id, dialogTree.selModel.selNode.attributes.id),
            method: 'GET',
            success: successTreeMoveHandler,
            failure: failureTreeMoveHandler
          };
          Ext.Ajax.request(requestConfig);

        };
        switch (selection) {
          case 'Grid':
            moveFromGrid();
            break;
          case 'Tree':
            moveFromTree();
            break;
        }
      };

      var addDialogButtons = function() {
        var el = Ext.fly('moveButton');
        var copyBtn = new Ext.Button({
          applyTo: 'moveButton',
          text: 'Move',
          id: 'MoveButton',
          handler: moveButtonHandler
        });


        var elc = Ext.fly('');
        var cancelBtn = new Ext.Button({
          applyTo: 'cancelButton',
          text: 'Close',
          id: 'CloseButton',
          handler: function() {
            dialog.hide();
          }
        });
      }
      addDialogButtons();
      dialog.setSize(600, 500);
      dialog.show();
    },
    NavigationCollapse: function(panel) {
      var components = SN.GUI.Components.Current;
      if (!components) return;
      var tb = components['Toolbar'];
      switch (panel.id) {
        case 'TreePane':
          Ext.getCmp('SearchPane').expand();
          tb.ToggleButton('tbSearchShow', true);
          break;
        case 'SearchPane':
          Ext.getCmp('TreePane').expand();
          tb.ToggleButton('tbFoldersShow', true);
          break;
      };
    },
    NavigationExpand: function(panel) {
    },
    ToggleSearchHandler: function(item, pressed) {
      var app = SN.ContentExplorer.Application;
      var components = SN.GUI.Components.Current;
      if (pressed) {
        Ext.getCmp('SearchPane').expand();
        components['Toolbar'].ToggleButton('tbFoldersShow', false);
      }
    },
    ToggleFoldersHandler: function(item, pressed) {
      var app = SN.ContentExplorer.Application;
      var components = SN.GUI.Components.Current;
      if (pressed) {
        Ext.getCmp('TreePane').expand();
        components['Toolbar'].ToggleButton('tbSearchShow', false);
      }
    },
    ViewModeHandler: function(item, e) {
      var button = Ext.get('tbView');
      var c = SN.GUI.Components.Current;
      var g = SN.GUI.Components.Current.Grid;
      var m = item.text.toLowerCase();
      if (g.options.viewMode == m) return;
      var n = item.parentMenu.items.items;
      for (var i = 0; i < n.length; i++) {
        n[i].setIconClass('snIconSmall_Checkbox_Out');
      }
      item.setIconClass('snIconSmall_Checkbox_In');
      c.SetSelectedControl('Tree');
      g.SwitchMode(m, c.id);
    }
  }
} ();

SN.ContentExplorer.Application = function() {
    /// This class is responsible for maintaining functionality of the client application of the .PortalExplorer.. 

    var mainViewContainer = null;
    var layoutBuilder;
    var components;
    var newSecurityDialog;

    var setErrorHandling = function() {
        var onEndRequest = function(sender, args) {
            var error = args.get_error();
            if (error != null) {
                args.set_errorHandled(true);
                var msg = args.get_response().get_responseData();
                Ext.MessageBox.show({
                    title: 'Error',
                    msg: msg,
                    buttons: Ext.MessageBox.OK,
                    icon: Ext.MessageBox.ERROR
                });
            }
        }
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);
    };

    return {
        Initialize: function() {
            Ext.apply(SN.ContentExplorer.Application, SN.ContentExplorer.initialConfiguration);
            setErrorHandling();
            components = SN.GUI.Components;
            layoutBuilder = SN.GUI.LayoutBuilder;
            layoutBuilder.BuildViewPort();
        },
        // ezek itt nem fognak kelleni
        ShowDialog: function(id) {
            if (id == null) id = 'Dialog';
            components.Current.GetInstance(id).show();
        },
        // deprecated!
        CloseNewContentDialog: function() {
            components.Current.GetInstance('ContentTypeDialog').hide();
        },
        CloseDialog: function(id) {
            components.Current.GetInstance(id).hide();
        },
        ClickOnGrid: function(nodeId, parentId) {
            components.Current.forceSelectedId = nodeId;
        },
        SearchPath: function() {
            var app = SN.ContentExplorer.Application;
            var el = Ext.fly(app.config.pathTextId);
            if (el) SN.GUI.Components.Current.ExpandTree(el.dom.value);
        },
        Search: function() {
            var app = SN.ContentExplorer.Application;
            var el = Ext.fly(app.config.searchTextId);
            if (el) SN.GUI.Components.Current.Search(el.dom.value);
        },
        createNewCtd: function() {
            var createNewCtdPageLoaded = function(sender, args) {
                components.Current.RemoveComponent('DialogGrid');
                var c = components.Current.CreateComponent('Dialog', 'ContentType');
                c.Instance().show();
                Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(createNewCtdPageLoaded);
            };
            var ctl = 'ForcePostBackButton', eventArgs, prm;
            var dialogGrid = components.Current.GetInstance('DialogGrid');
            if (dialogGrid.getSelectionModel().selections.length == 0) {
                Ext.Msg.alert('Information', 'Select a contenttype.');
                return;
            };

            components.Current.GetInstance('Dialog').hide();
            eventArgs = 'NewContentType;' + dialogGrid.selModel.getSelected().json.Name;
            prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_pageLoaded(createNewCtdPageLoaded);
            prm._doPostBack(ctl, eventArgs);
        }
    };
} ();

// This class is responsible for creating components which are being used on interface of the PortalExplorer and hold their context.

SN.GUI.Components = function() {

    // private fields
    var selectedControl = '';
    var app = SN.ContentExplorer.Application;
    var cns = SN.GUI.Components;

    // public fields
    this.id = '/Root';
    this.title = 'Root';
    this.rootID = '/Root';
    this.hasProperties = false;
    this.gridContainer;
    this.forceSelectedId = 0;

    // private methods
    function defaultPageLoaded(sender, args) {
        var t = SN.GUI.Components;
        t.RemoveComponent('DialogGrid');
        t.CreateComponent('Dialog', 'ContentType');
        Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(defaultPageLoaded);
    }

    function removeAllChildNodes(el) {
        if (!el) return;
        if (el.hasChildNodes()) {
            while (el.childNodes.length >= 1) {
                el.removeChild(el.firstChild);
            }
        }
    }

    // public methods

    this.GetVar = function(name) {
        if (data.constainsKey(name)) return data.get(name);
    }

    this.SetVar = function(name, value) {
        data.put(name, value);
    }

    this.GetSelectedControl = function() {
        return selectedControl;
    }

    this.SetSelectedControl = function(value) {
        var i = this.GetInstance(selectedControl);
        if (i != null) i.el.dom.className = i.el.dom.className.replace(' snSelectedControl', '');
        selectedControl = value;
        i = this.GetInstance(selectedControl);
        if (i != null) i.el.dom.className += ' snSelectedControl';
    }

    this.GetInstance = function(name, create) {
        if (!this.HasComponent(name)) {
            if (!create) return;
            this.CreateComponent(name);
        }
        var c = this[name];
        if (c != null) c = c.Instance();
        return c;
    }

    this.HasComponent = function(name) {
        return (typeof this[name] != 'undefined');
    }

    this.CreateComponent = function(type, subtype, el, options) {
        if (!cns[type]) return;
        var key;
        switch (type) {
            case 'Toolbar': key = type;
                break;
            default:
                key = (subtype != null ? subtype : '') + type;
                break;
        }
        if (this.HasComponent(key)) return this[key];
        var c = new cns[type](this, el, subtype, options);
        if (!c) return;
        this[key] = c;
        return c;
    }

    this.ExpandTree = function(text) {
        if (text) return this.Tree.Expand(text);
        var tree = this.GetInstance('Tree');
        if (!tree) return;
        tree.root.expand();
        tree.root.select();
    }

    this.GetSelectionType = function() {
        switch (selectedControl) {
            case 'Tree':
                var t = this.GetInstance(selectedControl).getSelectionModel().selNode;
                if (t != null) return selectedControl;
                break;
            default:
                return selectedControl;
        }
    }

    this.GetSelectedItems = function() {
        if (!this.HasComponent(selectedControl)) return;
        var component = this[selectedControl];
        switch (selectedControl) {
            case 'Grid':
                var s = '';
                var items = component.Instance().selModel.selections.items;
                for (var i = 0; i < items.length; i++) {
                    if (i != 0) s += ';';
                    s += items[i].json.Path;
                }
                return s;
                break;
            case 'Tree':
                return component.Instance().getSelectionModel().selNode.attributes.Path;
                break;
        }
    }

    this.RemoveComponent = function(name) {
        var c = this[name];
        if (c == null) return;
        c = c.Instance();
        if (c) c.destroy();
        delete this[name];
    }

    this.RemoveSelection = function(type) {
        var c = this.GetInstance(type);
        if (c == null) return;
        var s = c.getSelectionModel();
        if (typeof s != 'undefined') s.clearSelections();
    }

    this.RemoveAllChildNodes = function(ids) {
        var idlist = ids.split(' ');
        for (var i = 0; i < idlist.length; i++) {
            removeAllChildNodes(Ext.fly(idlist[i]).dom);
        }
    }

    this.RemoveUnnecessaryElements = function() {
        this.RemoveAllChildNodes('DialogTemplate DialogUpdatePanel DialogButtonsTemplate');
        this.RemoveComponent('DialogGrid');
    }

    this.SetPathText = function(path) {
        // !!!!!!!!!!!!!!!!! //
        this.id = path;
        var app = SN.ContentExplorer.Application;
        if (!app) return;
        var el = Ext.fly(app.config.pathTextId);
        if (el) el.dom.value = path;
    }

    this.Search = function(text) {
        return this.Grid.Search(text);
    }

    this.UpdateHeader = function(header, contentName, path) {
        var headerEl = Ext.fly('sn' + header + 'TabHeader');
        if (headerEl) {
            headerEl.dom.innerHTML = contentName;
            var c = document.createTextNode(path);
            var p = headerEl.dom.parentNode;
            if (p) {
                if (p.lastChild.nodeName !== "H2")
                    p.removeChild(p.lastChild);
                p.appendChild(c);
            }
        }
    }

    this.UpdateDialogHeader = function(node, messageFormat) {
        // Updates the html header of the dialog which is being used for displaying information about state of the copy.
        var text;
        var selection = this.GetSelectionType();
        if (!selection) return;

        var component = this.GetInstance(selection);
        switch (selection) {
            case 'Grid':
                text = String.format(messageFormat, this[selection].SelectionText());
                break;
            case 'Tree':
                text = String.format(messageFormat, component.getSelectionModel().selNode.attributes.Path);
                break;
        }
        Ext.fly('dialogHeaderTitle').dom.innerHTML = text;
        Ext.fly('commandTo').dom.innerHTML = (node != null ? node.attributes.Path : '');
    }
}
SN.GUI.Components.Dialog = function(context, element, subtype) {

  // private fields
  var app = SN.ContentExplorer.Application;
  var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
  var instance = null;
  var config;
  if (subtype == null) subtype = 'Default';

  // public fields
  this.parent = context;

  // private methods

  function getConfig(subtype) {
    switch (subtype) {
      case 'ContentType':
        return {
          id: 'MainWindowNewContent',
          applyTo: 'winNewContent',
          renderTo: 'form1',
          title: 'New content',
          width: 600,
          height: 500,
          modal: true,
          closeAction: 'hide'
        };
      default:
        return {
          id: 'MainWindow',
          applyTo: 'win',
          renderTo: 'form1',
          width: 600,
          height: 500,
          modal: true,
          closeAction: 'hide'
        };
    }
  }

  // public methods

  this.Instance = function() {
    return instance;
  }

  // constructor
  
  instance = new Ext.Window(getConfig(subtype));
  instance.on('hide', function() {
    context.Grid.Reload();
    context.Tree.Reload();
  });
};
SN.GUI.Components.Grid = function(context, element, subtype, options) {

    // private fields
    var app = SN.ContentExplorer.Application;
    var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
    var jsonStore = null;
    var instance;

    // public fields

    this.element = element;
    this.parent = context;
    this.options = (options || {});
    if (!this.options.viewMode) this.options.viewMode = 'details';

    // private methods

    function createDefaultGrid(el, options, url) {
        // Creates the grid component and binds the eventhandlers, loads the starting states of grid finally.
        jsonStore = getGridStore();
        jsonStore.on({
            'load': {
                fn: selectNewContentInGrid,
                scope: instance
            },
            'loadexception': {
                fn: function(v) {
                    alert('An exception has been occured during load - ' + v);
                },
                scope: instance
            }
        });
        config = getGridConfiguration(options);
        instance = new Ext.grid.GridPanel(config);
        var layout = SN.GUI.LayoutBuilder.ViewPort();

        // Ext column order bug: temporary hack
        if (options.viewMode == 'thumbnail' && config.columns[0].id == 'Name') {
            var tmp = config.columns[0];
            config.columns[0] = config.columns[1];
            config.columns[1] = tmp;
        }

        instance.getSelectionModel().on('rowselect', onGridRowSelect);
        instance.on('rowdblclick', onGridRowdblclick);
        instance.on('click', function() {
            context.SetSelectedControl('Grid');
        });

        var store = instance.store;
        store.proxy.conn.disableCaching = true;
        store.proxy.conn.timeout = 60000;
        store.setDefaultSort('Name', 'ASC');

        var p = Ext.getCmp(context.gridContainer);
        p.add(instance);
        p.doLayout();
        //p.getLayout().setActiveItem('grid');

        loadNode(url || SN.ContentExplorer.RootNodeId);

        if (context.hasProperties) {
            var treePanel = Ext.getCmp("TreePane");
            treePanel.on('expand', function(p) {
                loadNode(context.GetInstance('Tree').getSelectionModel().selNode.attributes.id);
            });
            var searchPanel = Ext.getCmp('SearchPane');
            searchPanel.on('expand', function(p) {
                instance.store.removeAll();
            });
        }
    }

    function doPostBackNewContentType(e, readKey) {
        if (readKey) {
            if (typeof (e) === 'undefined') return;
            if (e.getKey() != 13) return;
        }
        SN.GUI.Components.Current.GetInstance('Dialog').hide();
        var ctl = 'ForcePostBackButton';
        var eventArgs = 'NewContentType;' + Ext.getCmp('DialogGrid').selModel.getSelected().json.Name;
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_pageLoaded(selectNewContentTypePageLoaded);
        prm._doPostBack(ctl, eventArgs);
    }

    function createDialogGrid() {
        instance = new Ext.grid.GridPanel({
            id: 'DialogGrid',
            autoWidth: true,
            height: 290,
            autoScroll: true,
            frame: false,
            border: false,
            loadMask: true,
            hideHeaders: true,
            viewConfig: { forceFit: true },
            layout: 'fit',
            store: new Ext.data.JsonStore({
                id: 'DialogGridStore',
                url: urlList.getContentTypeNamesUrl,
                requestMethod: 'GET',
                fields: ['Id', 'Name', 'Path', 'Title', 'Description'],
                sortInfo: {
                    field: "Name",
                    direction: "DESC"
                }
                //               ,
                //                listeners: {
                //                    'loadexception': {
                //                        fn: function(a, b, c, d) {
                //                            alert('loadexception of grid store');
                //                        },
                //                        scope: this
                //                    },
                //                    'load': {
                //                        fn: function(a,b,c,d) {
                //                            alert('load of grid store');
                //                        },
                //                        scope: this
                //                    }
                //                }
            }),
            sm: new Ext.grid.RowSelectionModel({ singleSelect: true }),
            columns: [{
                id: 'Name',
                header: 'ContentType',
                sortable: true,
                //width: '100',
                dataIndex: 'Name',
                renderer: function(value, p, record) {
                    return String.format('<div class="snContentTypeRow snIconBig_{1}"><b>{0}</b><br/>{2}</div>', record.json.Title, record.json.Icon, record.json.Description);
                }
}]
            });

            instance.on('dblclick', function(e) {
                doPostBackNewContentType(e, false);
                //                SN.GUI.Components.Current.GetInstance('Dialog').hide();
                //                var ctl = 'ForcePostBackButton';
                //                var eventArgs = 'NewContentType;' + this.selModel.getSelected().json.Name;
                //                var prm = Sys.WebForms.PageRequestManager.getInstance();
                //                prm.add_pageLoaded(selectNewContentTypePageLoaded);
                //                prm._doPostBack(ctl, eventArgs);
            });
            instance.on('keypress', function(el) {
                doPostBackNewContentType(el, true);
                //                var c = el.getKey();
                //                if (c == 13) {
                //                    SN.GUI.Components.Current.GetInstance('Dialog').hide();
                //                    var ctl = 'ForcePostBackButton';
                //                    var eventArgs = 'NewContentType;' + this.selModel.getSelected().json.Name;
                //                    var prm = Sys.WebForms.PageRequestManager.getInstance();
                //                    prm.add_pageLoaded(selectNewContentTypePageLoaded);
                //                    prm._doPostBack(ctl, eventArgs);
                //                }
            });
            instance.on('keydown', function(el) {
                doPostBackNewContentType(el, true);
                //                var c = el.getKey();
                //                if (c == 13) {
                //                    SN.GUI.Components.Current.GetInstance('Dialog').hide();
                //                    var ctl = 'ForcePostBackButton';
                //                    var eventArgs = 'NewContentType;' + this.selModel.getSelected().json.Name;
                //                    var prm = Sys.WebForms.PageRequestManager.getInstance();
                //                    prm.add_pageLoaded(selectNewContentTypePageLoaded);
                //                    prm._doPostBack(ctl, eventArgs);
                //                }
            });



            instance.render('DialogUpdatePanel');
            instance.store.setDefaultSort('Name', 'ASC');
            instance.store.proxy.conn.url = urlList.getContentTypeNamesUrl;
            //instance.store.load({ requestMethod: 'GET' });
            instance.store.load();
        }

        function selectNewContentTypePageLoaded(sender, args) {
            context.RemoveComponent('DialogGrid');
            var d = context.CreateComponent('Dialog', 'ContentType');
            d.Instance().show();
            Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(selectNewContentTypePageLoaded);
        };

        function loadNode(url) {
            url = url + '';
            if (url.indexOf('.svc') == -1) url = String.format(urlList.gridLoaderUrl, url);
            instance.store.proxy.conn.url = url;
            instance.store.load();
            //            instance.store.load({
            //                params: {
            //                    start: 0,
            //                    limit: 25
            //                }
            //            });
        }


        function getGridStore() {
            return new Ext.data.JsonStore({
                id: 'GridStore',
                proxy: new Ext.data.HttpProxy({
                    url: urlList.gridLoaderUrl,
                    method: 'GET',
                    disableCaching: true
                }),
                root: 'Children',
                totalProperty: 'ChildCount',
                fields: SN.ContentExplorer.initialConfiguration.config.gridFields,
                sortInfo: {
                    field: "Index",
                    direction: "ASC"
                }
            });
        }

        function getGridColumnDefinition(args) {
            if (args && args.viewMode && args.viewMode == 'thumbnail') {
                var columns = [];
                columns[0] = {
                    id: 'Download',
                    header: '',
                    renderer: function(value, p, record) {
                        var j = record.json;
                        if (!j) return;
                        if (j.NodeTypeName == 'Image') {
                            return String.format('<div class="snThumbnail"><table border="0" cellspacing="0" cellpadding="0" class="snThumbnail-Table"><tr><td><img src="{0}?dynamicThumbnail=true&width=128&height=128" target="_blank" style="display:block;"/></td></tr></table></div>', record.json.Path);
                        }
                        return String.format('<div class="snThumbnail {0}"></div>', record.json.iconCls);
                    }
                };
                columns[1] = {
                    id: 'Name',
                    header: 'Name',
                    sortable: true,
                    dataIndex: 'Name',
                    renderer: function(value, p, record) {
                        return String.format('<div class="snIconNodeGrid">{0}</div>', value);
                    }
                };
                return columns;
            }
            return SN.ContentExplorer.initialConfiguration.config.gridColumns;
        }

        function createGridPagingToolbar() {
            // Returns a instance of Ext.PagingToolbar which is linked with jsonstore of the grid component.
            return new Ext.PagingToolbar({
                pageSize: 25,
                store: jsonStore,
                displayInfo: false,
                displayMsg: ' {0} - {1} of {2}',
                emptyMsg: "No rows",
                remoteSort: true
            });
        }

        function getGridPlugins() {
            var plugins = [new Ext.ux.grid.Search({ mode: 'local' })];
            return plugins;
        }

        function getGridConfiguration(args) {
            // Returns the configuration settings of grid.
            var app = SN.ContentExplorer.Application;
            var containerSize = Ext.getCmp(context.gridContainer).getSize();
            var config = {
                id: 'grid_' + context.gridContainer,
                store: jsonStore,
                columns: getGridColumnDefinition(args),
                sm: new Ext.grid.RowSelectionModel(
        { singleSelect: (args != null && args.singleSelectMode != null ? args.singleSelectMode === 'True' : false) }
      ),
                stripeRows: true,
                height: containerSize.height,
                width: containerSize.width,
                loadMask: false//,
                //bbar: [createGridPagingToolbar()]
            };
            if (args && args.viewMode && args.viewMode == 'thumbnail') {
                config.viewConfig = {
                    templates: {
                        master: new Ext.Template(
                    '<div class="x-grid3" hidefocus="true">',
                        '<div class="x-grid3-viewport x-grid3-thumbnail-view">',
                            '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset">{header}</div></div><div class="x-clear"></div></div>',
                            '<div class="x-grid3-scroller"><div class="x-grid3-body">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
                        "</div>",
                        '<div class="x-grid3-resize-marker">&#160;</div>',
                        '<div class="x-grid3-resize-proxy">&#160;</div>',
                    "</div>"
            ),
                        row: new Ext.Template(
                    '<div class="x-grid3-row x-grid3-thumbnail-row {alt}" style="{tstyle}">',
                    '{cells}',
                    '',
                    '</div>'
            ),
                        cell: new Ext.Template(
                    '',
                    '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
                    ''
            )
                    }
                };
            }
            return config;
        }

        function selectNewContentInGrid() {
            if (instance.beforeSelectNewContentInGrid) {
                var id = instance.beforeSelectNewContentInGrid();
                if (id !== -1)
                    context.forceSelectedId = id;
                instance.beforeSelectNewContentInGrid = null;
            };
            var nodeId = context.forceSelectedId;
            if (nodeId == null || nodeId == 0) return;
            var store = instance.store;
            if (store == null) return;
            var items = store.data.items;
            var rowIndex = -1;
            for (var i = 0; i < items.length; i++) {
                var id = items[i].json.Id;
                var intid = parseInt(id);
                if (intid == nodeId) {
                    rowIndex = i;
                    break
                }
            }
            if (rowIndex > -1) {
                context.forceSelectedId = 0;
                instance.getSelectionModel().selectRow(rowIndex);
                instance.fireEvent('rowclick', instance, rowIndex);
                return;
            }
            //alert("Not selected: " + nodeId);
        }

        function onGridRowSelect(selModel) {
            context.SetSelectedControl('Grid');
            if (context.hasProperties) {
                var ctl = 'ForcePostBackButton';
                var eventArgs = 'Grid;' + selModel.getSelected().json.Id;
                context.SetPathText(selModel.getSelected().json.Path);
                var headerText = String.format(SN.ContentExplorer.SR.VersionAndSecurityHeaderText, selModel.getSelected().json.Name, selModel.getSelected().json.ContentTypeName);
                //context.UpdateHeader('Version', headerText);
                //context.UpdateHeader('Security', headerText);
                context.UpdateHeader('Version', headerText, selModel.getSelected().json.Path);
                context.UpdateHeader('Security', headerText, selModel.getSelected().json.Path);
                var prm = Sys.WebForms.PageRequestManager.getInstance();
                prm._doPostBack(ctl, eventArgs);
            }
        }

        function onGridRowdblclick(grid, rowIndex, e) {
            var json = grid.selModel.getSelected().json;
            if (!json.leaf) context.ExpandTree(json.Path);
        }

        // public methods

        this.LoadNode = function(id) {
            return loadNode(id);
        }

        this.Instance = function() {
            return instance;
        }

        this.Search = function(searchExpression) {
            searchExpression = encodeURI(searchExpression);
            instance.store.proxy.conn.url = String.format(urlList.searchUrl, searchExpression);
            instance.store.load();
            //            instance.store.load({
            //                params: {
            //                    start: 0,
            //                    limit: 25
            //                }
            //            });
        }

        this.SelectionText = function() {
            var m = instance.selModel;
            var c = m.selections.getCount();
            if (c == 1) return m.getSelected().json.Path;
            return c;
        }

        this.SwitchMode = function(m, url) {
            instance.destroy();
            this.options.viewMode = m;
            createDefaultGrid(this.element, this.options, url);
        }

        this.ActualizeSize = function() {
            var containerSize = Ext.getCmp(context.gridContainer).getSize();
            this.instance.setWidth = containerSize.width;
            this.instance.setHeight = containerSize.height;
        }

        this.Reload = function() {
            /// Reloads the contents of the Grid by selectednode of the tree. 
            /// If Tree has not got selection, grid loads the children of the RootNode.
            var e, nodeId, selNode, tree, treeSelectedNode;
            try {
                selNode = instance.getSelectionModel().selNode;
                if (typeof selNode !== 'undefined') {
                    e = selNode.id;
                } else {
                    e = context.Tree.Instance().selModel.getSelectedNode().attributes.id;
                }
            } catch (ex) {
                e = SN.ContentExplorer.RootNodeId;
            }
            if (e == 0) return;
            nodeId = e;
            loadNode(nodeId);
            this.parent.SetSelectedControl('Tree');
        }

        // constructor

        switch (subtype) {
            case 'Dialog':
                createDialogGrid(this.element);
                break;
            default:
                createDefaultGrid(this.element, this.options);
                break;
        }
    }
SN.GUI.Components.Toolbar = function(context, element, subtype) {

    // private fields
    var app = SN.ContentExplorer.Application;
    var actions = SN.ContentExplorer.Actions;
    var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
    var instance;
    var buttonCaptions = {
        Actions: 'New Content',
        UploadFile: 'Upload Files'
    };
    var buttonIcons = {
        UploadFile: 'snIconSmallNew_File'
    }
    var buttonActions = {
        Actions: 'NewContentHandler',
        UploadFile: 'UploadHandler'
    }
    // public fields

    this.parent = context;

    // private methods

    function selectNewContentTypePageLoaded(sender, args) {
        components.RemoveComponent('DialogGrid');
        createNewContentTypeDialog();
        Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(selectNewContentTypePageLoaded);
    }

    function button(id, type) {
        switch (type) {
            case 'Toggle':
                return {
                id: 'tb' + id + 'Show',
                    itemId: 'tb' + id + 'Show',
                    text: id,
                    iconCls: 'snIconSmall_' + id,
                    enableToggle: true,
                    toggleHandler: actions['Toggle' + id + 'Handler'],
                    pressed: (id == 'Folders')
                };
            default:
                var o = {
                    id: 'tb' + id,
                    itemId: 'tb' + id,
                    iconCls: (typeof buttonIcons[id] == 'undefined' ? 'snIconSmall_' + id : buttonIcons[id]),
                    text: (typeof buttonCaptions[id] == 'undefined' ? id : buttonCaptions[id])
                };
                if (id == 'Views') {
                    o.menu = {
                        items: [
              { id: 'tbViewDetails', itemId: 'tbViewDetails', text: 'Details', handler: actions['ViewModeHandler'], iconCls: 'snIconSmall_Checkbox_In' },
              { id: 'tbViewThumbnail', itemId: 'tbViewThumbnail', text: 'Thumbnail', handler: actions['ViewModeHandler'], iconCls: 'snIconSmall_Checkbox_Out' }
              ]
                    }
                }
                if (type != null) o.xtype = 'tb' + type.toLowerCase();
                if (actions) o.handler = actions[(typeof buttonActions[id] == 'undefined' ? id + 'Handler' : buttonActions[id])];
                return new Ext.Toolbar[(type || '') + 'Button'](o);
        }
    }

    function getToolbarItems(subtype) {
        var b = [button('Actions'), button('UploadFile')];
        if (subtype != 'contentpicker') {
            b.push(button('Copy'), button('Move'), button('Delete'), button('Search', 'Toggle'), button('Folders', 'Toggle'), button('Views'));
        }
        return b;
    };

    this.ToggleButton = function(id, state) {
        instance.items.map[id].toggle(state);
    }

    this.Instance = function() {
        return instance;
    }

    instance = new Ext.Toolbar({
        id: 'Toolbar'//,
        //applyTo: (element || 'toolbar')
    });
    instance.add(getToolbarItems(subtype));
    instance.render(element || 'toolbar');
}
SN.GUI.Components.Tree = function(context, element, subtype) {
    // private fields
    var app = SN.ContentExplorer.Application;
    var urlList = SN.ContentExplorer.initialConfiguration.config.urlList;
    var instance;

    // public fields
    this.parent = context;

    // private methods
    function getTreeConfig(el) {
        return {
            el: el,
            animate: true,
            enableDD: false,
            containerScroll: true,
            autoHeight: true,
            border: false,
            rootVisible: true,
            expandable: true,
            loader: new Ext.tree.TreeLoader({
                requestMethod: 'GET',
                dataUrl: urlList.treeLoaderUrl
            })
        };
    }

    function updateProperties(node) {
        var headerText = String.format(SN.ContentExplorer.SR.VersionAndSecurityHeaderText, node.attributes.Name, node.attributes.ContentTypeName);
        context.UpdateHeader('Version', headerText, node.attributes.Path);
        context.UpdateHeader('Security', headerText, node.attributes.Path);

        var ctl = 'ForcePostBackButton';
        var eventArgs = 'Tree;' + node.id;
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm._doPostBack(ctl, eventArgs);
    }

    function onTreeSelectionChange(selModel, node) {
        if (node == null) return;
        context.SetSelectedControl('Tree');
        if (context.hasProperties) {
            context.SetPathText(node.attributes.Path);
            updateProperties(node);
        }
        var grid = context.GetInstance('Grid');
        if (!grid) return;
        var url = String.format(urlList.gridLoaderUrl, node.id);
        //    var m = (node.attributes.NodeTypeName == 'ImageGallery' ? 'thumbnail' : 'details');
        //    if (context.Grid.options.viewMode != m) {
        //      var views = Ext.get('tbViews');
        //      context.Grid.SwitchMode(m, url);
        //      return;
        //    }
        grid.store.proxy.conn.url = url;
        grid.store.load();
        //        grid.store.load({
        //            params: {
        //                start: 0,
        //                limit: 25
        //            }
        //        });
    }

    function onTreeNodeDragOver(dragOverEvent) {
        if (source.attributes.ContentType == "Site") dragOverEvent.cancel = true;
    }

    function reloadContextMenuHandler(item, e) {
        context.Tree.Reload();
        //if (item.parentMenu.selectedNode) item.parentMenu.selectedNode.reload();
    }

    function viewContextMenuHandler(item, e) {
        var tp = Ext.getCmp('CenterPaneTabPanel');
        var tab = new Ext.Panel({
            contentEl: SN.GUI.LayoutBuilder.CreateContainerElement('Dummy', null, true),
            title: item.parentMenu.selectedNode.attributes.Path,
            layout: 'fit',
            closable: true,
            xtype: "panel"
        });

        var t = tp.add(tab);
        tp.setActiveTab(t);
    }

    function createRootNode() {
        return new Ext.tree.AsyncTreeNode({
            text: context.title,
            id: context.id,
            Path: context.id,
            Text: context.title,
            Id: context.id,
            draggable: false
        });
    }

    // public methods
    this.AsyncTreeNode = function() {
        return new Ext.tree.AsyncTreeNode({
            nodeType: 'async',
            text: context.title,
            id: context.rootID,
            Id: context.rootID,
            Name: context.rootID
        });
    }

    this.Expand = function(path, attr, callback) {

        var preparePath = function(path) {
            path = path.replace("/Root/", "Root/");
            var lastIndex = path.lastIndexOf('/');
            if (lastIndex === path.length - 1) {
                path = path.substr(0, path.length - 1);
            }
            return path;
        }

        attr = attr || "Name";
        path = preparePath(path);
        var keys = path.split('/');
        var curNode = instance.getRootNode();

        var index = 1;
        var f = function() {
            if (++index == keys.length) {
                var s = curNode.findChild(attr, keys[index - 1]);
                if (s)
                    s.select();
                else {
                    curNode.select();
                    var g = SN.GUI.Components.Current.GetInstance('Grid');
                    if (g) {
                        g.beforeSelectNewContentInGrid = function() {
                            var store = g.store;
                            if (store == null) return -1;
                            var items = store.data.items;
                            var nodeId = -1;
                            for (var i = 0; i < items.length; i++) {
                                var nodeName = items[i].json.Name;
                                var currentName = keys[index - 1];
                                if (nodeName == currentName) {
                                    nodeId = items[i].json.Id;
                                    break;
                                }
                            }
                            return nodeId;
                        }
                    }
                }
                if (callback) {
                    callback(true, s);
                }
                return;
            }


            var c = curNode.findChild(attr, keys[index - 1]);

            if (!c) {
                if (callback) {
                    callback(false, curNode);
                }
                return;
            }
            curNode = c;
            c.expand(false, false, f);
        }
        curNode.expand(false, false, f);


    }

    this.Instance = function() {
        return instance;
    }

    this.Reload = function(root) {
        if (root) {
            context.id = root;
            context.title = root.substring(root.lastIndexOf('/') + 1);
            instance.root.id = root;
            instance.root.setText(context.title);
            instance.root.reload();
            return;
        }
        var e;
        try {
            e = instance.getSelectionModel().selNode;
        } catch (ex) { }
        if (e) e.reload();
    }

    // constructor

    var treeContextMenu = new Ext.menu.Menu({
        id: 'TreeContextMenu',
        items: [{
            text: 'Reload',
            handler: reloadContextMenuHandler
}]
        });
        //{
        //  text: 'View',
        //  handler: viewContextMenuHandler
        //}

        instance = new Ext.tree.TreePanel(getTreeConfig(element));
        var treeSorter = new Ext.tree.TreeSorter(instance, { folderSort: true, dir: 'asc' });
        instance.setRootNode(createRootNode());
        instance.render();
        instance.getSelectionModel().on('selectionchange', onTreeSelectionChange);
        instance.on('click', function(node) {
            context.SetSelectedControl('Tree');
            if (context.hasProperties) {
                context.SetPathText(node.attributes.Path);
                updateProperties(node);
            }
        });
        instance.on('contextmenu', function(node, e) {
            node.select();
            treeContextMenu.selectedNode = node;
            treeContextMenu.show(node.ui.getAnchor());
            return true;
        });
    }
SN.GUI.LayoutBuilder = function() {
  // LayoutBuilder is reponsible for creating parts of the PortalExplorer User Interface.
  var mainViewPort = null;
  var paneCollection = new Object();
  var isNumber = new RegExp('^\\d+$');
  var removeNumbers = new RegExp('\\d');
  var containers = new Ext.ux.Hashtable();
  var previousState = new Ext.ux.Hashtable();
  var presets = new Ext.ux.Hashtable();
  var contexts = new Array();
  var currentPreset = null;
  var currentContext = null;

  paneCollection.boxPane = function(args) {
    setDefault(args, 'id', 'ToolbarPane');
    setDefault(args, 'region', 'north');
    var o = { margins: '0 0 0 0' };
    containers.put('boxPane_Toolbar', 'toolbar');
    return new Ext.BoxComponent(apply(o, args));
  }

  paneCollection.toolbarPane = function(args) {
    setDefault(args, 'region', 'north');
    var o = {
      contentEl: args.el,
      autoScroll: true
    };
    return new Ext.Panel(apply(o, args, 'el'));
  }

  paneCollection.locationPane = function(args) {
    setDefault(args, 'id', 'LocationPane');
    setDefault(args, 'region', 'north');
    var o = {
      height: 30,
      margins: '0 0 0 0'
    };
    return new Ext.BoxComponent(apply(o, args));
  }

  paneCollection.navigationPane = function(args) {
    if (typeof args.items == 'undefined' || args.items.length == 0) {
      args.items = Array();
      args.items[0] = paneCollection.treePane({ el: createContainerElement('Tree'), title: 'Folders', id: 'TreePane' });
      args.items[1] = paneCollection.searchPane({ el: 'navPaneSearch' });
    }
    var o = new Ext.Panel(apply({
      id: 'NavigationPane',
      title: 'Navigation',
      split: true,
      autoScroll: true,
      collapsible: true,
      collapsed: false,
      width: 200,
      margins: '0 0 0 0',
      layout: 'accordion',
      layoutConfig: {
        animate: true,
        titleCollapse: true
      }}, args));
    o.items.items[0].on('expand', SN.ContentExplorer.Actions.NavigationExpand);
    o.items.items[1].on('expand', SN.ContentExplorer.Actions.NavigationExpand);
    o.items.items[0].on('collapse', SN.ContentExplorer.Actions.NavigationCollapse);
    o.items.items[1].on('collapse', SN.ContentExplorer.Actions.NavigationCollapse);
    return o;
  }

  paneCollection.treePane = function(args) {
    var o = {
      contentEl: args.el,
      autoScroll: true
    };
    return new Ext.Panel(apply(o, args, 'el'));
  }

  paneCollection.searchPane = function(args) {
    return {
      id: 'SearchPane',
      contentEl: args.el,
      title: 'Search'
    };
  }

  paneCollection.splitterPane = function(args) {
    setDefault(args, 'region', 'center');
    var o = {
      id: 'SplitterPane',
      layout: 'border',
      border: false,
      frame: false,
      split: true,
      header: false,
      margins: '0 0 0 0'
    };
    return apply(o, args);
  }

  paneCollection.centerPane = function(args) {
    setDefault(args, 'id', 'CenterPane');
    setDefault(args, 'region', 'center');
    var o = {
      split: true,
      layout: 'fit',
      tabPosition: 'top',
      border: false,
      frame: false,
      header: false,
      margins: '0 0 0 0',
      items: [this.gridPane({})]

      //      items: new Ext.TabPanel({
      //        id: 'CenterPaneTabPanel',
      //        frame: false,
      //        border: false,
      //        activeTab: 0,
      //        deferredRender: false,
      //        listeners: {
      //          beforeadd: function(o, c) {
      //            if (o.items.length > 0) o.unhideTabStripItem(o.items.items[0]);
      //          },
      //          beforeremove: function(o, c) {
      //            if (o.items.length == 2) o.hideTabStripItem(o.items.items[0]);
      //          }
      //        },
      //        items: [this.gridPane({ title: 'Grid' })]
      //      })
    };

    containers.put('centerPane_Grid', args.el);
    return apply(o, args);
  }

  paneCollection.gridPane = function(args) {
    setDefault(args, 'id', 'GridPane');
    setDefault(args, 'region', 'center');
    var o = {
      xtype: "panel",
      contentEl: createContainerElement(args.id + 'Div', null, true),
      layout: 'fit'
    };
    currentContext.gridContainer = args.id;
    return apply(o, args);
  }

  paneCollection.dataSheetPane = function(args) {
    return {
      xtype: "panel",
      id: 'DataSheetPane',
      contentEl: args.el,
      title: 'Datasheet',
      layout: 'fit'
    };
  }

  paneCollection.versionSheetPane = function(args) {
    return {
      xtype: "panel",
      id: 'VersionPanel',
      contentEl: args.el,
      title: 'Version history',
      layout: 'fit'
    };
  }

  paneCollection.securitySheetPane = function(args) {
    return {
      xtype: "panel",
      id: 'SecurityPanel',
      contentEl: args.el,
      title: 'Security',
      layout: 'fit'
    };
  }

  paneCollection.propertiesPane = function(args) {
    currentContext.hasProperties = true;
    setDefault(args, 'id', 'PropertiesPane');
    setDefault(args, 'region', 'east');
    if (typeof args.width == 'undefined' && args.region == 'east') args.width = 535;
    if (typeof args.height == 'undefined' && args.region == 'south') args.height = 300;
    if (typeof args.items == 'undefined' || args.items.length == 0) {
      args.items = Array();
      args.items[0] = paneCollection.dataSheetPane({ el: 'DataSheetUpdatePanel' });
      args.items[1] = paneCollection.versionSheetPane({ el: 'snVersionTab' });
      args.items[2] = paneCollection.securitySheetPane({ el: 'snSecurityTab' });
    }
    var o = {
      id: 'PropertiesPane',
      split: true,
      tabPosition: 'top',
      layout: 'fit',
      items: new Ext.TabPanel({
        frame: false,
        border: false,
        activeTab: 0,
        deferredRender: false,
        items: args.items
      })
    };
    return apply(o, args, 'items');
  }

  paneCollection.dummyPane = function(args) {
    return {
      region: args.region,
      title: args.title
    };
  }

  paneCollection.contentPickerDialog = function(args, handlers) {
    var container = document.createElement('DIV');
    container.className = "x-hidden";
    container.id = 'snContentPicker';
    document.body.appendChild(container);
    var o = {
      title: 'Contentpicker',
      applyTo: container,
      layout: 'border',
      resizable:true,
      buttons: [
        new Ext.Button({ id: 'cpOkButton', text: 'OK', handler: handlers.okButtonHandler }),
        new Ext.Button({ id: 'cpCancelButton', text: 'Cancel', handler: handlers.cancelButtonHandler })
      ]
    };
    return apply(o, args);
  }

  function apply(o, args, omit) {
    var omitx = ' ' + omit + ' ';
    for (var i in args) {
      if (omitx.indexOf(' ' + i + ' ') != -1) continue;
      o[i] = args[i];
    }
    return o;
  }

  function setDefault(args, prop, value) {
    if (typeof args[prop] == 'undefined') args[prop] = value;
  }

  var isComponent = function(type) {
    return SN.GUI.Components[type] && typeof SN.GUI.Components[type] == 'function';
  }

  var createContainerElement = function(name, id, omitInner) {
    if (!id) id = getFunctionName(name);
    var child;
    if (!omitInner && isComponent(name)) child = createContainerElement(name, id + '_' + name, true);
    var el = document.createElement('DIV');
    orig_id = id;
    var i = 2;
    while (containers.containsKey(id)) id = orig_id + i++;
    el.id = id;
    if (child != null) el.appendChild(child);
    containers.put(id, el);
    return el;
  }

  var getFunctionName = function(s) {
    if (s.indexOf('Dialog') != -1) return s.charAt(0).toLowerCase() + s.substring(1);
    return s.charAt(0).toLowerCase() + s.substring(1) + 'Pane';
  }

  var processNode = function(n, store) {
    if (n.nodeName.indexOf('#') != -1) return;

    var args = {};
    var name = n.nodeName;
    if (n.attributes != null) {
      for (var i = 0; i < n.attributes.length; i++) {
        var v = n.attributes[i].value;
        if (v == 'true' || v == 'false') v = (v == 'true');
        if (isNumber.exec(v)) v = parseInt(v);
        args[n.attributes[i].name] = v;
      }
    }
    if (n.firstChild) args.items = processChildNodes(n.firstChild, store);
    if (typeof args.el == 'undefined') args.el = createContainerElement(name);
    var json = store.paneCollection[getFunctionName(name)](args, store.options);
    return json;
  }

  var processChildNodes = function(n, store) {
    var items = [];
    if (n != null) {
      do {
        var component = processNode(n, store);
        if (component != null) items[items.length] = component;
        n = n.nextSibling;
      } while (n != null);
    }
    return items;
  }

  var viewsLoadCallback = function(wr) {
    currentContext = new SN.GUI.Components();
    if (this.options && this.options.rootFolderPath && this.options.rootFolderPath.indexOf('/') != -1) {
      currentContext.id = this.options.rootFolderPath;
      currentContext.title = this.options.rootFolderPath.substring(this.options.rootFolderPath.lastIndexOf('/') + 1);
    }
    contexts[contexts.length] = currentContext;
    var cfg = { id: 'Layout', layout: 'border', items: [] };
    var q = Ext.DomQuery;
    var i = 0;
    var l = wr.records.length;
    var node = null;
    do {
      node = wr.records[i].node;
      i++;
    } while (i <= l && q.selectValue('@id', node, 0) != this.preset);
    if (i <= l) {
      var first = node.firstChild;
      if (first.nodeName.indexOf('#') != -1) first = first.nextSibling;
      if (first.nodeName.indexOf('Dialog') != -1) {
        cfg = processNode(first, this);
        presets.put(this.preset, new Ext.Window(cfg));

      } else {
        cfg.items = processChildNodes(node.firstChild, this);
        presets.put(this.preset, new Ext.FormViewport(cfg));
        currentPreset = this.preset;
        var cptp = Ext.getCmp('CenterPaneTabPanel');
        if (cptp) cptp.hideTabStripItem(currentContext.gridContainer);
      }
    }

    var keys = containers.keys();
    for (var i = 0; i < keys.length; i++) {
      if (previousState.containsKey(keys[i])) continue;
      previousState.put(keys[i], '');
      if (keys[i].indexOf('_') != -1) {
        var x = keys[i].split('_');
        var type = x[1].replace(removeNumbers, '');
        var p = (type == 'Toolbar' ? this.preset : null);
        if (!currentContext.CreateComponent(type, p, containers.get(keys[i]), this.options)) {
          var newcntx = new SN.GUI.Components();
          newcntx.CreateComponent(type, p, containers.get(keys[i]), this.options);
        }
      }
    }
    currentContext.ExpandTree();
    if (typeof SN.GUI.Components.Current == 'undefined') {
      SN.GUI.Components.Current = currentContext;
    }
    if (this.finishCallback) this.finishCallback({ dialog: presets.get(this.preset), context: currentContext });
  }

  return {
    ViewPort: function(name) {
      if (!name) name = currentPreset;
      if (presets.containsKey(name)) return presets.get(name);
    },
    BuildViewPort: function(preset, callback, options) {
      if (!preset) preset = 'explorer_landscape';
      var ds = new Ext.data.Store({
        url: '/views.xml', reader: new Ext.data.XmlReader({
          record: 'View',
          id: '@id'
        }, []),
        preset: preset,
        loadRecords: viewsLoadCallback,
        paneCollection: paneCollection,
        finishCallback: callback,
        options: options
      });
      ds.load();
    },
    CreateContainerElement: function(name, id, omitInner) {
      return createContainerElement(name, id, omitInner);
    }
  };
} ();
Ext.namespace("SN", "SN.PortalRemoteControl");

SN.createFloatingBehaviorByCssName = function(cssName, handlerCssName){
    var elements = Sys.UI.DomElement.getElementsByClassName(cssName);
    if (elements) {
        for (var i = 0, l = elements.length; i < l; i++) {
            var el = elements[i];
            var dragEl = Ext.get(el);
            dragEl.dd = new Ext.dd.DD(dragEl, 'group3');
            var selectedElements = Ext.select('.' + handlerCssName, false, el);
            dragEl.dd.setHandleElId(selectedElements.elements[0]);
            
        }
    }
}

var PortalRemoteControl = {
    /// Collection of functions for operating of PRC
    PRCToggle: function(element){
        var el = Ext.fly(element);
        var isElVisible = el.isVisible();
        
        if (isElVisible) {
            el.replaceClass('PortalRemoteControlShow', 'PortalRemoteControlClose');
            return;
        };
        el.replaceClass('PortalRemoteControlClose', 'PortalRemoteControlShow');
    },
   
    GetWindowSize: function(){
        var w = 0;
        var h = 0;
        
        //IE
        if (!window.innerWidth) {
            //strict mode
            if (!(document.documentElement.clientWidth == 0)) {
                w = document.documentElement.clientWidth;
                h = document.documentElement.clientHeight;
            }
            //quirks mode
            else {
                w = document.body.clientWidth;
                h = document.body.clientHeight;
            }
        }
        //w3c
        else {
            w = window.innerWidth;
            h = window.innerHeight;
        }
        return {
            width: w,
            height: h
        };
        
    },
    
    PRCDD_onMouseUp: function(e){
        var xl, yl;
        var lel = this.getEl();
        
        var windowSize = PortalRemoteControl.GetWindowSize();
        var dragElXY = Ext.fly(lel).getXY();
        xl = dragElXY[0] < 0 ? 0 : dragElXY[0];
        yl = dragElXY[1] < 0 ? 0 : dragElXY[1];
        
        xl = xl < windowSize.width - 30 ? xl : windowSize.width - 240;
        yl = yl < windowSize.height - 30 ? yl : windowSize.height - 360;
        
        Ext.get(lel).setX(xl);
        Ext.get(lel).setY(yl);
        
        ASPCode.net.CookieManager.setCookie('prc-x', xl);
        ASPCode.net.CookieManager.setCookie('prc-y', yl);
    },
    
    PRCMakeDraggable: function(ctl, handler){
    
        var setDragAndDrop = function(){
            var elHnd = Sys.UI.DomElement.getElementsByClassName(handler, el)[0];
            var prcDragEl = Ext.get(elHnd.parentNode);
            prcDragEl.dd = new Ext.dd.DD(prcDragEl, 'prc-group');
            prcDragEl.dd.onMouseUp = PortalRemoteControl.PRCDD_onMouseUp;
        }
        
        var el = $get(ctl);
        if (el) {
            setDragAndDrop();
        }
    },
    
    PRCInitialize2: function(ctl, handler){
    
        var prcShowCookie = ASPCode.net.CookieManager.getCookie('prc-show');
        if (prcShowCookie == 'true') {
            var prcx = ASPCode.net.CookieManager.getCookie('prc-x');
            var prcy = ASPCode.net.CookieManager.getCookie('prc-y');
            
            if (prcx == null || prcx == 'undefined') 
                prcx = 100;
            if (prcy == null || prcy == 'undefined') 
                prcy = 100;
            
            //Ext.fly('PortalRemoteControl').setX(prcx);
            //Ext.fly('PortalRemoteControl').setY(prcy);
            
            var prcEl = $get('PortalRemoteControl');
            Sys.UI.DomElement.setLocation(prcEl, parseInt(prcx), parseInt(prcy));
            
            if (prcEl.style.display !== 'none') {
                $get('PRC-Icon').style.display = 'none';
            }
            else {
                prcEl.style.display = '';
            }
        }
        else {
            $get('PortalRemoteControl').style.display = 'none';
            $get('PRC-Icon').style.display = '';
        }
        
        //this.PRCToggle('PRC-Icon');
        this.PRCMakeDraggable(ctl, handler);
    },
    
    PRCInitialize: function(ctl, handler){
        var prcShowCookie = ASPCode.net.CookieManager.getCookie('prc-show');
        if (prcShowCookie == 'true') {
            var prcx = ASPCode.net.CookieManager.getCookie('prc-x');
            var prcy = ASPCode.net.CookieManager.getCookie('prc-y');
            
            if (prcx == null || prcx == 'undefined') 
                prcx = 100;
            if (prcy == null || prcy == 'undefined') 
                prcy = 100;
            
            //Ext.fly('PortalRemoteControl').setX(prcx);
            //Ext.fly('PortalRemoteControl').setY(prcy);
            
            var prcEl = $get('PortalRemoteControl');
            Sys.UI.DomElement.setLocation(prcEl, parseInt(prcx), parseInt(prcy));
            
            var isPrcVisible = Sys.UI.DomElement.containsCssClass(prcEl, 'PortalRemoteControlShow');
            if (!isPrcVisible) {
                Sys.UI.DomElement.addCssClass(prcEl, 'PortalRemoteControlShow');
            }
        }
        else {
            Sys.UI.DomElement.addCssClass($get('PortalRemoteControl'), 'PortalRemoteControlClose');
            Sys.UI.DomElement.addCssClass($get('PRC-Icon'), 'PortalRemoteControlShow');
        }
        
        //this.PRCToggle('PRC-Icon');
        this.PRCMakeDraggable(ctl, handler);
    },
    
    PRCClose: function(){
        ASPCode.net.CookieManager.setCookie('prc-show', null);
        this.PRCToggle('PortalRemoteControl');
        this.PRCToggle('PRC-Icon');
    },
    
    PRCOpen: function(){
        var prcx = ASPCode.net.CookieManager.getCookie('prc-x');
        var prcy = ASPCode.net.CookieManager.getCookie('prc-y');
        
        if (prcx == null || prcx == 'undefined') 
            prcx = 100;
        if (prcy == null || prcy == 'undefined') 
            prcy = 100;
        //Ext.fly('PortalRemoteControl').setX(prcx);
        //Ext.fly('PortalRemoteControl').setY(prcy);
        Sys.UI.DomElement.setLocation($get('PortalRemoteControl'), parseInt(prcx), parseInt(prcy));
        
        this.PRCToggle('PortalRemoteControl');
        this.PRCToggle('PRC-Icon');
        
        ASPCode.net.CookieManager.setCookie('prc-show', 'true');
    }

}

SN.PortalRemoteControl.Application = function(){
    /// PortalRemoteControl application
    var dialogId = null;
    var dialog = null;
    var GetDialogConfig = function(){
        return {
            id: dialogId,
            applyTo: dialogId,
            renderTo: 'form1',
            y: 25,
            width: 500,
            height: 300,
            modal: true,
            closeAction: 'hide'
        };
    };
    
    var CreateDialog = function(){
        if (!dialog) {
            dialog = new Ext.Window(GetDialogConfig());
        };
            };
    
    return {
        initialize: function(){
        
        },
        showDialog: function(id, dw, dh, head){
            dialogId = id;
            var w = dw, h = dh;
            CreateDialog();
            if (w || h) {
                dialog.setSize({
                    width: w,
                    height: h
                });
                dialog.setTitle(head);
            };
            dialog.show();
        },
        
        closeDialog: function(id){
        
            Ext.WindowMgr.get(id).hide();
        }
        
    }
}();




/// <reference path="jquery/jquery.vsdoc.js"/>

var WorkspaceIconView = function() {
    function onIconClick(event, icon) {
        selectIcon(icon);
        setHash(icon);
        event.preventDefault();
    }
    function onIconDoubleClick(event, icon) {
        var defaultAction = $("#Actions_" + icon.attr("id") + " .snWsDefaultAction");
        if (defaultAction.hasClass("snWsMsieOnly"))
            defaultAction = icon;
        window.location = defaultAction.attr("href");
        event.preventDefault();
    }
    function setSelectedOnLoad(hash) {
        strippedHash = hash.substring(1);
        if (strippedHash != "") {
            selected = getSelectedFromHash(strippedHash);
            if (selected != "")
                selectIcon($("#" + selected));
        }
    }
    function getSelectedFromHash(hash) {
        dict = hash.split("=");
        if (dict[0] == "selected")
            return decodeURIComponent(dict[1]);
        else
            return "";
    }
    function setHash(icon) {
        if (icon.attr("id") != "")
            window.location.hash = "selected=" + encodeURIComponent(icon.attr("id"));
    }
    function selectIcon(icon) {
        unselectIcons();
        $(".snWsJsEnabledDetailsSkin .snPtBody").load(encodeURI(icon.attr("sn:DetailsAction")+"&containingPage="+encodeURIComponent(location.href)));
        icon.addClass("snWsSelected");
    }
    function unselectIcons() {
        $(".snWsJsEnabledFolderViewSkin .snWsSelected").removeClass("snWsSelected");
        //    $(".snWsJsEnabledDetailsSkin .snPtBody").children().remove();
    }
    return {
        // HACK!
        flyMeToTheMoonHack: function() {
            $(".snWsJsFlyMeToTheMoon").prependTo(".snWsJsEnabledToolbarSkin .snPtBody");
        },
        enableJsControls: function() {
            $(".snWsJsOnly").removeClass("snWsJsOnly");
            if ($.browser.msie)
                $(".snWsMsieOnly").removeClass("snWsMsieOnly");
        },
        installFunctionality: function() {
            setSelectedOnLoad(window.location.hash);
            $(".snWsJsEnabledFolderViewSkin a.snWsJsEnabledItem").click(function(event) {
                onIconClick(event, $(this));
            });
            $(".snWsJsEnabledFolderViewSkin a.snWsJsEnabledItem").dblclick(function(event) {
                onIconDoubleClick(event, $(this));
            });
        }
    }
} ();

$(document).ready(function() {
    // HACK!
    WorkspaceIconView.flyMeToTheMoonHack();
    WorkspaceIconView.enableJsControls();
    WorkspaceIconView.installFunctionality();
});

function OpenDocument(url) {
    try {
        EditDocumentButton = new ActiveXObject("SharePoint.OpenDocuments");
        if (EditDocumentButton) {
            if (url.substr(url.length - 4, url.length - 1) == ".ppt") {
                EditDocumentButton.EditDocument(url, "PowerPoint.Slide");
            }
            else {
                EditDocumentButton.EditDocument(url);
            }

            event.cancelBubble = false;
            event.returnValue = false;
        }
    }
    catch (e) {
    }
}

function BrowseFolder(src) {
    var webFolderTarget = null;
    var webFolderSsrc = null;
    var webFolderDiv = null;
    var urlPattern = "http://[a-zA-Z0-9\-\.]+(:80)?/";
    var urlPatternRegexp = new RegExp(urlPattern, 'gi');
    var target = '_blank';

    if (src.charAt(0) == '/') src = "http://" + document.location.host + src;
    webFolderSrc = src;
    webFolderTarget = target;

    if (webFolderDiv == null) {
        webFolderDiv = document.createElement('div');
        document.body.appendChild(webFolderDiv);
        webFolderDiv.onreadystatechange = BrowseFolder;
        webFolderDiv.addBehavior('#default#httpFolder');
    }
    if (webFolderDiv.readyState == "complete") {
        webFolderDiv.onreadystatechange = null;
        var success = false;
        var targetFrame = null;

        try {
            targetFrame = document.frames.item(webFolderTarget);
            if (targetFrame != null) targetFrame.document.body.innerText = 'WebFolder not found';
        } catch (e) { }

        try {
            var ret = webFolderDiv.navigateFrame(webFolderSrc, webFolderTarget);
            if (ret == "OK") success = true;
        }
        catch (e) { }

        if (!success && webFolderSrc.search(urlPattern) == 0) {
            var sUrl = httpFolderSource.replace(urlPatternRegexp, "//$1/").replace('/', "\\");
            if (targetFrame != null) {
                try {
                  targetFrame.onload = null;
                  targetFrame.document.location.href = sUrl;
                  success = true;
                }
                catch (e) { }
            }
        }

        if (!success) alert('Error');
    }
}

