var BrVer = new Object();
BrVer.ua = navigator.userAgent.toLowerCase();

BrVer.isDOM = (document.getElementById) ? true : false;

BrVer.isOpera  = BrVer.isOpera5 = (window.opera && BrVer.isDOM || false);
BrVer.isOpera6 = BrVer.isOpera && window.print;
BrVer.isOpera7 = BrVer.isOpera && (BrVer.ua.indexOf("opera 7") > 0 || BrVer.ua.indexOf("opera/7") >= 0);
BrVer.isOpera8 = BrVer.isOpera && (BrVer.ua.indexOf("opera 8") > 0 || BrVer.ua.indexOf("opera/8") >= 0);
BrVer.isOpera9 = BrVer.isOpera && (BrVer.ua.indexOf("opera/9") >= 0);
BrVer.isOpera92 = BrVer.isOpera && (BrVer.ua.indexOf("opera/9.2") >= 0 && BrVer.ua.indexOf("opera/9.20") < 0 && BrVer.ua.indexOf("opera/9.21") < 0);
BrVer.isOpera95 = BrVer.isOpera && (BrVer.ua.indexOf("opera/9.5") >= 0);
BrVer.isOpera10 = BrVer.isOpera && (BrVer.ua.indexOf("opera/10") >= 0);

BrVer.isMSIE   = BrVer.isIE = document.all && document.all.item && !BrVer.isOpera;
BrVer.isMSIE6  = BrVer.isMSIE && navigator.appVersion.indexOf('MSIE 6') >= 0;
BrVer.isMSIE7  = BrVer.isMSIE && navigator.appVersion.indexOf('MSIE 7') >= 0;
BrVer.isMSIE8  = BrVer.isMSIE && navigator.appVersion.indexOf('MSIE 8') >= 0;
BrVer.isMSIE87 = BrVer.isMSIE7 && navigator.appVersion.indexOf('Trident/4.') >= 0;
BrVer.isMSIE9  = BrVer.isMSIE && navigator.appVersion.indexOf('MSIE 9') >= 0;
BrVer.isMSIE1x  = BrVer.isMSIE && navigator.appVersion.indexOf('MSIE 1') >= 0;
BrVer.isMSIEQuirks = BrVer.isMSIE && document.compatMode === "BackCompat";

BrVer.isNC     = navigator.appName == "Netscape";
BrVer.isNC4    = BrVer.isNC && !BrVer.isDOM;
BrVer.isNC6    = BrVer.isMozilla = BrVer.isNC && BrVer.isDOM;
BrVer.isFireFox= !BrVer.isOpera && BrVer.ua.indexOf("firefox/") > -1;
BrVer.isFF15   = BrVer.isFireFox && BrVer.ua.indexOf("firefox/1.5") > -1;
BrVer.isFF1    = !BrVer.isFF15 && BrVer.ua.indexOf("firefox/1.") > -1;
BrVer.isFF2    = BrVer.isFireFox && BrVer.ua.indexOf("firefox/2") > -1;
BrVer.isFF3    = BrVer.isFireFox && BrVer.ua.indexOf("firefox/3") > -1;
BrVer.isFF30   = BrVer.isFireFox && BrVer.ua.indexOf("firefox/3.0") > -1;
BrVer.isFF35   = BrVer.isFireFox && BrVer.ua.indexOf("firefox/3.5") > -1;
BrVer.isFF36   = BrVer.isFireFox && BrVer.ua.indexOf("firefox/3.6") > -1;
BrVer.isFF37   = BrVer.isFireFox && BrVer.ua.indexOf("firefox/3.7") > -1;
BrVer.isFF4    = BrVer.isFireFox && BrVer.ua.indexOf("firefox/4") > -1;
BrVer.isFF35plus = BrVer.isFF35 || BrVer.isFF36 || BrVer.isFF37 || BrVer.isFF4;
BrVer.isFF36plus = BrVer.isFF36 || BrVer.isFF37 || BrVer.isFF4;

BrVer.isWebKit = (BrVer.ua.indexOf("safari") > -1 || BrVer.ua.indexOf("webkit") > -1 || BrVer.ua.indexOf("khtml") > -1) && !BrVer.isOpera;
BrVer.isSafari = BrVer.isWebKit && BrVer.ua.indexOf("chrome/") < 0;
BrVer.isSafari2 = BrVer.isSafari && BrVer.ua.indexOf('webkit/5') > -1 && BrVer.ua.indexOf('version/2') > -1;
BrVer.isSafari3 = BrVer.isSafari && BrVer.ua.indexOf('webkit/5') > -1 && BrVer.ua.indexOf('version/3') > -1;
BrVer.isSafari4 = BrVer.isSafari && BrVer.ua.indexOf('webkit/5') > -1 && BrVer.ua.indexOf('version/4') > -1;
BrVer.isSafari5 = BrVer.isSafari && BrVer.ua.indexOf('webkit/5') > -1 && BrVer.ua.indexOf('version/5') > -1;

BrVer.isChrome = BrVer.isWebKit && BrVer.ua.indexOf("chrome/") > -1;
BrVer.isChrome1 = BrVer.isChrome && BrVer.ua.indexOf("chrome/1") > -1;
BrVer.isChrome2 = BrVer.isChrome && BrVer.ua.indexOf("chrome/2") > -1;
BrVer.isChrome3 = BrVer.isChrome && BrVer.ua.indexOf("chrome/3") > -1;
BrVer.isChrome4 = BrVer.isChrome && BrVer.ua.indexOf("chrome/4") > -1;

BrVer.isGecko  = !BrVer.isSafari && BrVer.ua.indexOf("gecko") > -1;

if (!('Ext' in window))
    window.Ext = {};
else Ext.onReady(function() {
    if (BrVer.isMSIE87) Ext.getBody().addClass('ext-ie87');
    if (BrVer.isMSIE) Ext.getBody().addClass('ext-ie-'+document.compatMode);
});
Ext.tree.MultiSelectionModel.override({
   onKeyDown: Ext.emptyFn
});
// workaround for FireFox bug "Permission denied to access property 'nodeType' from a non-chrome context"
// (occurs when jiggling the mouse over scrollbars)
// Does not work :(
// source: http://extjs.com/forum/showthread.php?t=74765&page=12
/*
Ext.override(Ext.Element, {
    contains: function() {
        var isXUL = Ext.isGecko ? function(node) {
            var s = Object.prototype.toString.call(node);
            return s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]';
        } : Ext.emptyFn;

        return function(el) {
            return !this.dom.firstChild || // if this Element has no children, return false immediately
                   !el ||
                   isXUL(el) ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
        };
    }(),
});
*/

Ext.docware = function() {
    var msgCt;

    function createBox(t, s, d) {
        var add = d?" danger":"";
        return ['<div class="msg'+d+'">',
                '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
                '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3>', t, '</h3>', s, '</div></div></div>',
                '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
                '</div>'].join('');
    }
    return {
        msg : function(title, format, danger) {
            var delay = window.Documena && window.Documena.user && window.Documena.user.infodelay || 1;
            if (!msgCt) {
                msgCt = Ext.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
            }
            msgCt.alignTo(document, 't-t');
            var s = String.format.apply(String, Array.prototype.slice.call(arguments, 1));
            var m = Ext.DomHelper.append(msgCt, {html:createBox(title, s, danger)}, true);
            m.slideIn('t').pause(delay).ghost("t", {remove:true});
        },
        setLabel: function(id, text, keepRedStar) {
            var _id = typeof id === 'string' ? id : typeof id === 'object' && id.id ? id.id : '';
            var x = $('#x-form-el-'+_id).parent().find('>label').get(0);
            if (!x) return;
            var red = keepRedStar ? $(x).find('span.redstar').get(0) : null;
            if (!red) {
                x.innerHTML = text || "";
                return;
            }
            var parent = red.parentNode;
            while (parent.firstChild === red && parent !== x) {
                red = parent; parent = red.parentNode;
            }
            while (parent.firstChild !== red) parent.removeChild(parent.firstChild);
            parent.innerHTML = (text || "") + parent.innerHTML;
        },
        allowBlank: function(id) {
            var _id = typeof id === 'string' ? id : typeof id === 'object' && id.id ? id.id : '';
            var cmp = typeof id === 'object' ? id : Ext.getCmp(_id);
            if (!cmp) return;
            cmp.allowBlank = true;
            try { cmp.validate(); } catch (e) {}
            $('#x-form-el-'+_id).parent().find('>label span.redstar').hide();
        }
    };
}();
window.Documena.Ext = Ext.docware;

function newItemChanged(obj,event,base){
    var ndesAll = base.getSelectionModel().tree.nodeHash;
    for(var i in ndesAll){
        if(ndesAll[i] && ndesAll[i].attributes){
            if((""+ndesAll[i].attributes["id"]).indexOf('parentID_') != -1){
                if($("#"+ndesAll[i].attributes["id"]).get(0).value.trim()==""){
                    ndesAll[i].unselect();
                }
            }
        }
    }
}

function newItemClicker(obj,evt){
    evt.cancelBubble = true;
    return false;
}


function delay(iMs) {
    var iStart = new Date;
    while (new Date - iStart < iMs) {
    }
    ;
}

function OpenDocument(win, url ) {
    var editor;
    try {
        editor = new ActiveXObject("SharePoint.OpenDocuments.2");
    } catch ( e) {
    }
    try {
        editor = new ActiveXObject("SharePoint.OpenDocuments.3");
    } catch ( e) {
    }
    try {
        editor = new ActiveXObject("SharePoint.OpenDocuments.1");
    } catch ( e) {
    }
    if( editor != null) {
        full_url = document.location.protocol+"//"+document.location.host+decodeURI(url);
        try {
        if(!editor.EditDocument2(win, full_url))
            throw ('error while open ' + url);
        } catch (e) {
        	win.document.location.href = full_url;
        }
    } else {
        win.document.location.href = url + (url.indexOf('?') > 0 ? "&rnd=" : "?rnd=")+Math.random();
    }
}
function openDocumenaMainWindow() {
    var root = document.location.protocol+"//"+document.location.host;
    var w = window.open("", 'Documena');
    if (!w) return;
    if (w.location && w.location != 'about:blank') { 
        try {
            if (w.location.host == location.host) {
                w.alert(_T('activated.by.user.request', window.metainfoobj ? window.metainfoobj.title : ""));
                return;
            }
        } catch (e) {
        }
        w.location = root;
    } else
        w.location = root;
}
Documena.fn.register = function(evt, file) {
    if (!Documena.modules) Documena.modules = {};
    Documena.modules[evt] = file;
}
Documena.fn.publish = function(evt, data) {
    if (Documena.modules && Documena.modules[evt])
        js.include(Documena.modules[evt], "", null);
    OpenAjax.hub.publish(evt, data);
}
Documena.fn.registered = function(evt) {
    return Documena.modules && (evt in Documena.modules);
}

if (!"".endsWith) {
    String.prototype.endsWith = function(s) {
        if (typeof s !== 'string') return false;
        if (!s) return true;
        var p = this.length - s.length;
        if (p < 0) return false;
        if (p === 0) return this == s;
        return this.indexOf(s, p) === p;
    }
}
if (!"".startsWith) {
    String.prototype.startsWith = function(s) {
        if (typeof s !== 'string') return false;
        if (!s) return true;
        var p = this.length - s.length;
        if (p < 0) return false;
        if (p === 0) return this == s;
        return this.lastIndexOf(s, 0) === 0;
    }
}
Array.prototype.append = function(a) {
    for (var i = 0; i < arguments.length; i++) this.push(arguments[i]);
    return this;
}
function encodeUx(s) {
    if (!s) return "";
    var t = typeof s;
    if (t === 'number' || t === 'boolean') return s;
    if (t !== 'string') return "";
    t = new Array();
    for (var i = 0; i < s.length; i++) t.push(s.charCodeAt(i));
    return "u" + t.join('u');
}

BrVer.metrix = {
    "border": {
        "MSIE":{
            "thin":2, "medium":4, "thick":6
        },
        "FF":{
            "thin":1, "medium":3, "thick":5
        },
        "Opera":{
            "thin":1, "medium":3, "thick":6
        },
        "Safari3":{
            "thin":1, "medium":3, "thick":5
        },
        "Chrome":{
            "thin":1, "medium":3, "thick":5
        }
    }
};
BrVer.metrix["border"]["Safari"]  = BrVer.metrix["border"]["Safari3"];
BrVer.metrix["border"]["Safari4"] = BrVer.metrix["border"]["Safari3"];

BrVer.getMetrix = function(type, value) {
    var m = BrVer.metrix[type];
    if (!m) return null;
    var code = [];
    if (BrVer.isOpera) {
        if (BrVer.isOpera95) { 
            code[code.length] = "Opera9.5"; 
            code[code.length] = "Opera9.2"; 
            code[code.length] = "Opera9"; 
        } else
        if (BrVer.isOpera92) { 
            code[code.length] = "Opera9.2"; 
            code[code.length] = "Opera9"; 
        } else
        if (BrVer.isOpera9) code[code.length] = "Opera9"; else
        if (BrVer.isOpera8) code[code.length] = "Opera8"; else
        if (BrVer.isOpera7) code[code.length] = "Opera7"; else
        if (BrVer.isOpera6) code[code.length] = "Opera6";

        code[code.length] = "Opera";
    } else
    if (BrVer.isMSIE) {
        if (BrVer.isMSIE6) code[code.length] = "MSIE6"; else
        if (BrVer.isMSIE7) code[code.length] = "MSIE7"; else
        if (BrVer.isMSIE8) code[code.length] = "MSIE8"; else
        code[code.length] = "MSIE";
    } else
    if (BrVer.isFireFox) {
        if (BrVer.isFF1) code[code.length] = "FF1"; else
        if (BrVer.isFF15) code[code.length] = "FF1.5"; else
        if (BrVer.isFF2) code[code.length] = "FF2"; else
        if (BrVer.isFF3) code[code.length] = "FF3";
        code[code.length] = "FF";
    } else
    if (BrVer.isSafari) {
        if (BrVer.isSafari4) {
            code[code.length] = "Safari4"; 
            code[code.length] = "Safari3"; 
        }
        else if (BrVer.isSafari3) code[code.length] = "Safari3"; 
        else code[code.length] = "Safari2";
        code[code.length] = "Safari";
    } else
    if (BrVer.isChrome) {
        code[code.length] = "Chrome";
    }
    for (var i = 0; i < code.length; i++) if (m[code[i]]) return m[code[i]];
    return null;
}

function css2int(val, el, property) {
    if (!val) return 0;
    var e = null;
    if (typeof(val) == "number") e = val; else
    if (typeof(val) == "string") {
        val = val.trim();
        if (val.endsWith(";")) val = val.substring(0, val.length - 1);
        
        if (val.endsWith("px")) {
            e = parseInt(val); 
        } else
        if (val.endsWith("em")) {
        } else
        if (val.endsWith("pt")) {
        } else
        if (val == "medium" || val == "thin" || val == "thick") {
            e = BrVer.getMetrix(property || "border", val);
        } else
        if (val.endsWith("%")) {
            if (el && el.parentNode) {
                var p = el.parentNode;
                var w = Math.max(p.offsetWidth, p.clientWidth);
                if (!w) {
                    var e = new Ext.Element(p);
                    w = css2int(e.getStyle('width'), p, "width");
                }
                var percent = parseInt(val);
                e = Math.round(w * percent / 100);
            }
        }
    }

    return (!e || isNaN(e)) ? 0 : e;
}

function adjustSize(cfg) {
    cfg = Ext.applyIf(cfg ? cfg : {}, {
        width:false,
        height:true,
        component:null,
        parents:null,
        marginBottom:0,
        marginRight:0,
        chain:null,
        debug:false
    });
    if (cfg.parents) 
        for (var i = 0; i<cfg.parents.length; i++) 
            cfg.parents[i] = Ext.applyIf(cfg.parents[i], { marginRight:0, marginBottom:0, id:null, skip:false, skipWidth:false, skipHeight:false });

    return function(c) {
        try {
            var target = Ext.getCmp(cfg.component);
        } catch (e) {
            if (cfg.debug) throw e;
        }
        if (target) {
            var pos = [];
            var obj = [];
            var ready = false;
            try {
                obj[0] = c;
                if (cfg.parents) for (var i = 0; i < cfg.parents.length; i++) obj[obj.length] = Ext.getCmp(cfg.parents[i].id);
                obj[obj.length] = target;
                for (i = 0; i < obj.length; i++) pos[i] = obj[i].getPosition();
                ready = true;
            } catch (e) {
            }
            var pcnt = cfg.parents ? cfg.parents.length : 0;
            if (ready) {
                var w = obj[0].getInnerWidth();
                // IE workaround
                var parentComponents = [];
                var p = obj[0];
                while (p) {
                    p = p.findParentBy(function(p, c) { return (p.getInnerWidth) ? true : false });
                    if (p) parentComponents[parentComponents.length] = p;
                }
                //window.PARENTS=parentComponents;
                if (parentComponents && parentComponents.length > 0) {
                    var minWidth = w;
                    var minWidthEl = null;
                    for (i = 0; i < parentComponents.length; i++) {
                        try {
                            var _w = parentComponents[i].getInnerWidth();
                            if (_w < minWidth) {
                                minWidth = _w; minWidthEl = parentComponents[i].getEl();
                            }
                            //alert(i+": "+_w+", id="+parentComponents[i].getId());
                        } catch (e) {
                        }
                    }
                    //alert("source width="+w+", minWidth="+minWidth);
                    if (minWidth < w) {
                        var el = obj[0].getEl().parent();
                        w = minWidth;
                        while (el) {
                            var dom = el.dom;
                            var margins = css2int(el.getStyle('margin-left'), dom, "margin") + css2int(el.getStyle('margin-right'), dom, "margin");
                            var paddings = css2int(el.getStyle('padding-left'), dom, "padding") + css2int(el.getStyle('padding-right'), dom, "padding");
                            var borders = css2int(el.getStyle('border-left-width'), dom, "border") + css2int(el.getStyle('border-right-width'), dom, "border");
                            w = w - margins - paddings - borders;
                            //if (!confirm("_m='"+_margin+"', m_='"+margin_+"', _p='"+_padding+"', p_='"+padding_+"', _b='"+_border+"', b_='"+border_+"'")) break;
                            if (el == minWidthEl) break;
                            el = el.parent();
                        }
                        //alert("source width="+obj[0].getInnerWidth()+", minWidth="+minWidth+", calculated width="+w);
                    }
                }

                var h = obj[0].getInnerHeight()
                if (cfg.height) {
                    for (i = 1; i < obj.length; i++) {
                        var offsTop = pos[i][1] - pos[i-1][1];
                        h = h - offsTop - (i > pcnt ? cfg.marginBottom : cfg.parents[i-1].marginBottom);
                        if (i > pcnt || !(cfg.parents[i-1].skipHeight || cfg.parents[i-1].skip)) obj[i].setHeight(h);
                    }
                }
                if (cfg.width) {
                    //alert("Inner width = "+w);
                    for (i = 1; i < obj.length; i++) {
                        var offsLeft = pos[i][0] - pos[i-1][0];
                        w = w - offsLeft - (i > pcnt ? cfg.marginRight : cfg.parents[i-1].marginRight);
                        if (i > pcnt || !(cfg.parents[i-1].skipWidth || cfg.parents[i-1].skip)) {
                            //alert("obj["+i+"].setWidth("+w+"); ");
                            obj[i].setWidth(w);
                        }
                    }
                }
            }
        }
        if (cfg.chain) cfg.chain(c);
    }
}
function intCompareDesc(a, b) { return b-a }

function clone(o) {
 if(!o || 'object' !== typeof o)  {
   return o;
 }
 var c = 'function' === typeof o.pop ? [] : {};
 var p, v;
 for(p in o) {
 if(o.hasOwnProperty(p)) {
  v = o[p];
  if(v && 'object' === typeof v) {
    c[p] = clone(v);
  }
  else {
    c[p] = v;
  }
 }
}
 return c;
}
function isObjectEmpty(o) {
    if (!o) return true;
    if (typeof o !== 'object') return true;
    for (var i in o) {
        if (typeof o[i] !== 'function') return false;
    }
    return true;
}
var defaultDateRenderer = Ext.util.Format.dateRenderer('d.m.y H:i');
var dateRenderer = function(value, metadata, record, rowIndex, colIndex, store) {
    if (typeof value === 'string') value = parseInt(value);
    if (typeof value === 'number') value = new Date(value < 4070898000 ? value * 1000 : value);
    var d = (value instanceof Date) ? value : null;
    if (!d) return "-";
    return defaultDateRenderer(d, metadata, record, rowIndex, colIndex, store);
}
var defaultGroupRenderer = function(value, unused, record, rowIndex, colIndex, store) {
    return value;
}
var titleBaseRenderer = function(value, metadata, record, rowIndex, colIndex, store) {
     return value;
}

var userSelectorClick = function (a, b) {
    OpenAjax.hub.publish("ru.ktelabs.documena.dialog.userlist.cliked", {id:a,name:b});
}

window.Documena.fn.doSearch = function() {
    OpenAjax.hub.publish("ru.ktelabs.documena.search.run");
}
window.Documena.fn.doRefresh = function() {
    OpenAjax.hub.publish("ru.ktelabs.documena.bc.update.navigation");
    OpenAjax.hub.publish("ru.ktelabs.documena.bc.update.objects");
    OpenAjax.hub.publish("ru.ktelabs.documena.search.run");
}
OpenAjax.hub.subscribe('ru.ktelabs.documena.actions.refresh', window.Documena.fn.doRefresh);

function showContextHelp(w) {
    var page = document.location.pathname;
    var winId = w;
    if (arguments.length === 0) {
        var win = Ext.WindowMgr.getActive();
        winId = win ? win.getId() : null;
    }
    var tabPanelDOM = $(winId ? "#"+winId : document).find(".x-tab-panel").get(0);
    var tabPanel = tabPanelDOM ? Ext.getCmp(tabPanelDOM.getAttribute("id")) : null;
    var tab = null;
    if (tabPanel && tabPanel.isVisible()) tab = tabPanel.getActiveTab().getId();
    var helpWin = window.open("/docs/help.jsp?page="+page+(win ? "&w="+winId : "")+(tab ? "&f="+tab+".html" : ""), "HELP_PAGE");
}
function wndCtxtHelp(winid) {
    return function() { showContextHelp(winid); }
}
function formatFileSize(size){
    if(size < 1024) {
        return size + " " + _T("common.size.bytes", size);
    }
    var value, units;
    if(size < 1048576) {
        value = size / 1024;
        units = "common.size.kbytes";
    } else if(size < 1073741824) {
        value = size / 1048576;
        units = "common.size.mbytes";
    } else  {
        value = size / 1073741824;
        units = "common.size.gbytes";
    }
    return Ext.util.Format.number(value, value < 70 ? '0.0' : '0') + _T(units);
}

function localeDateRenderer(dt, fmt) {
    var f = (fmt || 'd F Y').replace(/(^|[^\\])F/,"$1*")
    var d = dt;
    if (!dt || !dt.format || !dt.getMonth) d = (typeof dt == 'number' || typeof dt == 'string') ? new Date(dt) : new Date();
    var m = d.getMonth();
    return d.format(f).replace(/\*/, _T('_of_month.'+m));
}

function decodeTomcatError(response) {
    if (!response || !response.replace) return "";
    return response.replace(/.+<body><h1>(.+?)<\/h1>.+/, "$1");
}
function checkUUID(s) {
    //return s && /[A-Z]{2,10}-[0-9]{6,}/.test(s);
    return s && /[A-Z]{2,10}-[0-9][0-9A-Z][0-9]{2,}[0-9A-Z][0-9]/.test(s);
}
function uuid2id(s) {
    if (!s) return null;
    //var id = s.replace(/^[A-Z]{2,10}-([0-9])[0-9]([0-9]+)[0-9]([0-9])$/, '$1$2$3');
    var id = s.replace(/^[A-Z]{2,10}-([0-9])[0-9A-Z]([0-9]+)[0-9A-Z]([0-9])$/, '$1$2$3');
    //alert('uuid2id("'+s+'")="'+id+'"');
    return id === s ? null : parseInt(id);
}
function getFolderById(id) {
    if (!id) return null;
    var data = $g(window, 'objects', 'rawdata', 'folders');
    if (data && data.length)
        for (var i = 0; i < data.length; i++) {
            var f = data[i];
            if (f && f[0] == id) return {'id':f[0], 'name':f[1], 'count':f[2], 'type':f[3]};
        }
    return null;
}
function findFolderById(id) {
    return getFolderById(id) || {};
}
function getRecordByDocid(docid) {
   if (!window.gs) return null;
   var data = window.gs.getStore().getRange();
   if (!data) return null;
   for (var i = 0; i < data.length; i++) {
       var row = data[i].data;
       if (row.docid == docid) return row;
   }
   return null;
}
function extractDocumentIdAndUUID(data) {
    if (!data) return null;
    var docid = null;
    var uuid = null;
    if (typeof data == 'number') docid = data; else
    if (typeof data == 'string') {
        if (!checkUUID(data)) return null;
        uuid = data;
    } else
    if (typeof data.length == 'number') {
        if (data.length < 1) return null;
        var result = new Array();
        for (var i = 0; i < data.length; i++) {
            if (!data[i]) continue;
            var t = extractDocumentIdAndUUID(data[i]);
            if (!t) continue;
            if (t.length) for (var j = 0; j < t.length; j++) if (t[j].docid) result.push(t[j]);
        }
        return result.length > 0 ? result : null;
    } else
    if (typeof data.uuid == 'string') {
        if (!checkUUID(data.uuid)) return null;
        uuid = data.uuid;
        if (typeof data.docid == 'number') docid = data.docid;
    } else
    if (typeof data.data == 'object' && typeof data.data.uuid == 'string') {
        if (!checkUUID(data.data.uuid)) return null;
        uuid = data.data.uuid;
        if (typeof data.data.docid == 'number') docid = data.data.docid;
    }

    if (!docid) {
        if (uuid) docid = uuid2id(uuid); else return null;
    }
    if (!uuid) {
        var record = getRecordByDocid(docid);
        if (record && record.uuid) uuid = record.uuid; // else return null;
    }

    return [uuid ? {'docid':docid, 'uuid':uuid} : {'docid':docid}];
}
/**
 * getDocumentInfoFields([data,] 'field1', 'field2', ....);
 * data - docid 
 *        or [docid1, docid2, ...] 
 *        or ['uuid1', 'uuid2', ...]
 *        or [{docid:docid1}, {docid:docid2}, ...]  (result of extractDocumentIdAndUUID)
 *        or grid.getSelectionModel().getSelections()
 *        or grid.getSelectionModel().getSelected()
 *        or an array of grid.getSelectionModel().getSelected().data
 *        or gird instance
 * default 'data' value is window.gs. If 'data' is null, returns null
 * returns [{docid:.., uuid:..., field1:.., field2:..}]  OR  null
 */
function getDocumentInfoFields() {
    if (arguments.length == 0) return null;
    if (!arguments[0]) return null; // getDocumentInfoFields(null, ....)
    var idx = 0;
    var data = typeof arguments[0] == 'object' ? arguments[idx++] : (typeof arguments[0] == 'number' ? [{'docid':arguments[idx++]}] : window.gs);
    if (!data) return null;
    if (typeof data.getSelectionModel == 'function') data = data.getSelectionModel().getSelections();
    if (!data || idx >= arguments.length) return null;
    if (!('length' in data)) data = [data];
    if (data.length < 1) return null;
    
    var docid = false;
    var uuid = false;
    var _data = false;
    var fields = 0;
    if (typeof data[0] == 'number') {
        docid = true;
        var temp = new Array();
        for (var i = 0; i < data.length; i++) temp.push({'docid':data[i]});
        data = temp;
    }
    else
    if (typeof data[0] == 'string') {
        docid = true;
        var temp = new Array();
        for (var i = 0; i < data.length; i++) {
            var id = uuid2id(data[i]);
            if (id) temp.push({'docid':id});
        }
        if (!temp.length) return null;
        data = temp;
    }
    else
    for (var i in data[0]) {
        if (typeof data[0][i] == 'function') continue;
        if (i == 'docid') docid = true; else
        if (i == 'uuid' ) uuid  = true; else
        if (i == 'data' ) { _data = true; break; } else
        fields++;
    }
    
    if (!_data && !docid) return null;
    
    var result = new Array();
    for (var i = 0; i < data.length; i++) {
        var record;
        if (_data) record = data[i].data; else
        if (fields == 0) record = getRecordByDocid(data[i].docid); else
        record = data[i];
        if (typeof record != 'object') continue;

        var set = {};
        set.docid = record.docid;
        set.uuid  = record.uuid;
        var count = 0;
        for (var j = idx; j < arguments.length; j++) {
            var name = arguments[j];
            if (typeof name != 'string') continue;
            if (name == 'docid' || name == 'uuid') continue;
            if (name in record) { set[name] = record[name]; count++; }
        }
        if (count > 0) result.push(set);
    }
    return result.length > 0 ? result : null;
}

function joinFields(data, separator, quotes, field) {
    var f = field || 'name';
    if (!data || !data.length) return "";
    var result = new Array();
    for (var i = 0; i < data.length; i++) {
        if (!data[i]) continue;
        var s = (typeof data[i] == 'string') ? data[i] : (f in data[i])  ? data[i][f] : null;
        if (!s) continue;
        if (quotes) {
            if (!separator) {
                result.push(quotes);
                result.push(s);
                result.push(quotes);
            } else
                result.push(quotes + s + quotes);
        } else {
            result.push(s);
        }
    }
    return result.length > 0 ? result.join(separator) : "";
}

function arrayOfFields(data, field, unwrapSingleItem) {
    var idx = typeof field === 'number';
    var f = (idx || typeof field === 'string') ? field : 'docid';
    var u = (typeof field === 'boolean') ? field : unwrapSingleItem;

    if (!data || !data.length) return null;
    var result = new Array();
    for (var i = 0; i < data.length; i++) {
        var row = data[i];
        if (!row) continue;
        
        var v = null;
        if (idx) { if (row instanceof Array && row.length > f) v = row[f]; } 
        else if (typeof row === 'number') v = row;
        else if (f in row) v = row[f];

        if (v) result.push(v);
    }
    return result.length > 0 ? (result.length == 1 && u ? result[0] : result) : null;
}

/**
 * data: [ [id, name, .....], ...]
 * checkboxes (optional): [{id:, label:, value:}]
 * title
 * message
 * fn: function(name, id, formdata)
 * text (optional): initial value
 * width (optional)
 * height (optional)
 * validator (optional): function(value, config.validationConfig, formdata, data)
 * forceSelection (optional, =false): true to restrict the selected value to one of the values in the list
 * combo (optional, =true): false to use simple text input instead of combo
 */
window.Documena.fn.prompt = function(config) {
    if (!config || !config.fn) return;

    var id = config.id || ("prompt"+(new Date()).getTime());
    var store = new Array();
    if (config.data && config.data.length)
        for (var i = 0; i < config.data.length; i++) store.push([config.data[i][0], config.data[i][1]]);
    var cbcount = config.checkboxes ? config.checkboxes.length || 0 : 0;
    var w = config.width || (Math.max(config.title.length, config.message.length) > 50 ? 500 : 300);
    var cw = w / 7;
    var h = config.height || (Math.floor((Math.max(config.title.length, config.message.length) + cw - 1) / cw)*16+cbcount*20+115);

    var formValidator = function() {
        var cmp = Ext.getCmp(id+'_id');
        var name = cmp.getRawValue();
        var formdata = {};
        if (cbcount > 0) {
            for (var i = 0; i < cbcount; i++) {
                var cbcfg = config.checkboxes[i];
                if (!cbcfg || !cbcfg.id) continue;
                var cb = Ext.getCmp(id+'_cb_'+i);
                if (cb) formdata[cbcfg.id] = cb.getValue();
            }
        }
        if (config.validator)
            name = config.validator(name, config.validationConfig || config.validatorConfig, formdata, config.data);
        return {'name':name, 'formdata':formdata};
    }
    var comboListeners = {};
    /*if (config.validator)*/
    var btnState = function() {
        var v = formValidator();
        var ok = Ext.getCmp(id+"_btnOk");
        if (ok) ok.setDisabled(!(v && v.name));
    }
    comboListeners['blur'] = btnState;
    
    var promptItems = [];
    var xType = 'combo' in config ? (config.combo ? 'combo' : 'textfield') : 'combo';
    promptItems.push({xtype: xType, id:id+'_id', name:id+'_name', width: (w-40), typeAhead: true, typeAheadDelay:0, store: store, fieldLabel: config.message, mode: 'local', enableKeyEvents: true, listeners:comboListeners});
    for (var i = 0; i < cbcount; i++) {
        var cb = config.checkboxes[i];
        if (!cb.id || !cb.label) { if (!config.height) h=h-20; continue; }
        promptItems.push({xtype: 'checkbox', id:id+'_cb_'+i, hideLabel: true, boxLabel:cb.label, value:(cb.value?"true":"false")});
    }

    var okButton = function() {
        var v = formValidator();
        if (!v || !v.name) return;
        var value = '';
        for (var i=0; i < store.length; i++) {
            var item = store[i];
            if (!item.length || item.length < 2) continue;
            if (v.name == item[1]) { value = item[0]; break; }
        }
        config.fn(v.name, value, v.formdata);
        dialog.close();
    };

    var btnOkInitialState = !config.text;
    if (!btnOkInitialState && config.validator) {  
        var initialFormData = {};
        for (var i = 0; i < cbcount; i++) {
            var cb = config.checkboxes[i];
            if (cb.id) initialFormData[cb.id] = cb.value ? true : false;
        }
        btnOkInitialState = !config.validator(config.text, config.validationConfig || config.validatorConfig, initialFormData, config.data);
    }
    
    var panel = new Ext.FormPanel({
        border:false, labelAlign: 'top', autoWidth:true, autoHeight: true, items: promptItems
    });
    var dialog = new Ext.Window({
        title: config.title,
        id: id+'_w',
        resizable: false,
        width: w,
        height: h,
        modal: true,
        shadow: true,
        autoScroll: true,
        bodyStyle:'padding:5px; background-color: white;',
        buttonAlign:'center',
        layout: 'fit',
        forceSelection: config.forceSelection || false,
        items: panel,
        tools: [ {id: "help", qtip: _T('docview.help'), handler:showContextHelp }],
        closeAction: 'close',
        buttons: [
            {'text': (config.ok || "OK"), 'id': (id+'_btnOk'), handler: okButton, disabled:btnOkInitialState},
            {'text': (config.cancel || _T('create.folder.cancel')), handler: function() { dialog.close(); } }
        ],
        listeners: {
            afterrender: function() {
                panel.items.each(function(item, idx, total) {
                    var xt = item.getXType();
                    if (xt != 'textfield' && xt != 'textarea' && xt != 'combo') return;
                    item.on('keypress', btnState, item, { buffer: 1200 });
                    item.on('change', btnState);
                });
            },
            beforedestroy: function() {
                panel.items.each(function(item, idx, total) {
                    var xt = item.getXType();
                    if (xt != 'textfield' && xt != 'textarea' && xt!='combo') return;
                    item.un('keypress', btnState);
                    item.un('change', btnState);
                });
            }
        }
    });
    dialog.show();
    if (config.text) {
        var combo = Ext.getCmp(id+'_id');
        if (combo) combo.setRawValue(config.text);
    }
} /* Documena.fn.prompt */
window.Documena.fn.promptValidators = {};
window.Documena.fn.promptValidators.normalize = function(name) {
    return name && name.replace(/\s*([\s.,;:]\s?)\s*/g, '$1').replace(/^\s+|\s+$/g, '');
}
window.Documena.fn.promptValidators.noDupes = function(name, vcfg, formdata, data) {
    if (!name) return name;
    var normalize = function(s) { return s && s.replace(/[\s.,;:!\-]/g, '') };
    var normname = normalize(name);
    if (data && data instanceof Array) {
        for (var i = 0; i < data.length; i++) {
            var row = data[i];
            if (row && row.length > 1 && normalize(row[1]) == normname) return null;
        }
    }
    return name;
}
window.Documena.fn.promptValidators.exclude = function(name, vcfg, formdata, data) {
    if (!vcfg || typeof vcfg.exclude !== 'object' || !vcfg.exclude.length) return name;
    return window.Documena.fn.promptValidators.noDupes(name, vcfg, formdata, vcfg.exclude);
}
window.Documena.fn.promptValidators.chain = function() {
    if (!arguments.length) return null;
    var fns = new Array();
    for (var i = 0; i < arguments.length; i++) {
        var arg = arguments[i];
        if (typeof arg === 'function') {
            fns.push(arg); continue;
        }
        if (typeof arg !== 'object' || typeof arg.fn !== 'function') continue;
        if (!arg.data) {
            fns.push(arg.fn); continue;
        }
        var fn = function(func, data) {return function(name, vcfg, formdata) { return func(name, vcfg, formdata, data); };}(arg.fn, arg.data);
        fns.push(fn);
    }
    
    if (fns.length == 0) return null;

    return function(name, vcfg, formdata, data) {
        for (var i = 0; i < fns.length && name; i++)
            name = fns[i](name, vcfg, formdata, data);
        return name;
    };
}

window.Documena.fn.viewDocument = function(evt, data) {
    if (!data) return;
    var ids = extractDocumentIdAndUUID(typeof data == 'object' && 'docs' in data ? data.docs : data);
    if (!ids || !ids.length) return;
    for (var i = 0; i < ids.length; i++) {
        var purl = ids[i].uuid ? true : false;
        var url = purl ? ids[i].uuid : ('docview.jsp?id='+ids[i].docid);
        if (typeof data == 'object' && 'tab' in data) {
            if (purl) url = url + "/"+data.tab; else url = url + "&tab="+data.tab;
        }
        var uri = "/docs/"+url;
        var param= "VIEW_DOCUMENT_PAGE"+ids[i].docid;
        Ext.docware.msg(emptyMessageConstant,_T('main.windowdoc.open'));
        var myWin = window.open(uri,param);
        if(myWin) {
            if (window.topcontentscroll)
                $("#" + window.topcontentscroll.id).find("li[docid='"+ids[i].docid+"']").remove();
            myWin.focus();
        }
    }
}
OpenAjax.hub.subscribe('ru.ktelabs.documena.actions.view', window.Documena.fn.viewDocument);

window.Documena.fn.openDocument = function(evt, data) {
    var docs = getDocumentInfoFields(extractDocumentIdAndUUID(data), 'actions'/*'jcr'*/);
    if (!docs) return;

    var confidential = false;
    var ids = new Array();
    for (var i = 0; i < docs.length; i++) {
        var r = docs[i];
        if (r.actions._flags.confidential === true) 
            confidential = true;
        ids.push(r.docid);
    }
    var docscount = ids.length;
    ids = ids.join(',');

    var openDocuments = function(urls) {
        for (var i = 0; i < urls.length; i++) {
            var open = function(u) { return function(){
                OpenDocument(window, u);
            }}(urls[i]);
            setTimeout(open, i * 5000 + 250);
        }
    }

    var getURLs = function(ids, pwd) {
        var p = {id:ids};
        p.dav = BrVer.isIE ? 'true' : 'false';
        if (pwd) p.pwd = pwd;
        Ext.Ajax.request({
            url: '/docs/ajax/webdav_urls.jsp',
            method: 'POST',
            params: p,
            success: function(response, params) {
                var data = Ext.util.JSON.decode(response.responseText);
                if (data.success && data.urls && data.urls.length) openDocuments(data.urls);
            },
            failure: function(response, params) {
                Ext.MessageBox.alert(infoMessageConstant, _T("open.webdav.geturl.error", docscount));
            }
        });
    }

    if (confidential) {
        Documena.confidential.getPassword({
            okHandler:function(pwd) { getURLs(ids, pwd); }
        });
    } else {
        getURLs(ids);
    }
}
OpenAjax.hub.subscribe('ru.ktelabs.documena.actions.open', window.Documena.fn.openDocument);

window.Documena.dbg = function(msg) {
    if (!msg) return;
    var body = document.body || document.documentElement;
    body.insertBefore(document.createComment(msg), document.body.firstChild);
};

window.Documena.fn.dialog = function(config) {
    var id = config.id || ('dialog'+new Date().getTime());
    var btns = new Array();
    var be = null;
    if (config.buttons && config.buttons.length) {
        for (var i = 0; i < config.buttons.length; i++) {
            var b = config.buttons[i];
            if (!b) continue;
            if (b instanceof Ext.Button) btns.push(b);
            else if (typeof b.handler === 'function') {
                if (b.enableIf && b.enableIf instanceof Array) {
                    if (!b.id) b.id = id+"_btn_"+btns.length;
                    if (!be) be = {};
                    be[b.id] = b.enableIf;
                }
                btns.push(new Ext.Button(b));
            }
        }
    }
    if (config.cancelButton !== false) {
        var cancel;
        if (config.cancelCallback) {
            cancel = function() {
                Ext.Ajax.request({
                    url: config.cancelCallback,
                    success: function(response, dataValue) {
                        dialog.close();
                    },
                    failure: function(response, params) {
                        Ext.MessageBox.alert(_T('admin.common.alert'), _T(config.cancelCallbackError, response ? decodeTomcatError(response.responseText) : ""));
                    }
                });
            }
        } else {
            cancel = function() { dialog.close(); }
        }
        btns.push({text:config.cancelButton || _T('cancel.button'), handler:cancel});
    }
    var fields = new Array();
    if (config.fields) {
        for (var i = 0; i < config.fields.length; i++) {
            var f = config.fields[i];
            if (!f) continue;
            if (f.xtype) {
                if (be) f.enableKeyEvents = true;
            }
            fields.push(f);
        }
    }
    var pcfg = {
        id: config.id || (id+'_f'),
        border: false, 
        title:false,
        autoScroll: true,
        labelAlign: config.labelAlign || 'left',
        labelWidth: 'labelWidth' in config ? config.labelWidth : (!config.labelAlign || config.labelAlign === 'left') ? 140 : 0,
        labelSeparator: 'labelSeparator' in config ? config.labelSeparator : ':',
        defaults: {anchor:'-22'},
        items: fields
    };
    if (config.noDefaultAnchor) delete pcfg.defaults.anchor;
    if ('url' in config) pcfg.url = config.url;
    if ('hideLabel' in config) pcfg.hideLabel = config.hideLabel;
    var panel = new Ext.form.FormPanel(pcfg);
    var wcfg = {
        title: config.title,
        id: id+'_w',
        resizable: config.resizable || false,
        modal: true,
        shadow: true,
        bodyStyle:'padding:5px; background-color: white;',
        buttonAlign:'center',
        layout: 'fit',
        forceSelection: config.forceSelection || false,
        items: panel,
        tools: [ {id: "help", qtip: _T('docview.help'), handler:showContextHelp }],
        closeAction: 'close',
        buttons: btns,
        listeners: config.listeners || {}
    };
    if (config.width && config.width !== 'auto') {
        wcfg.width = config.width;
    } else {
        wcfg.autoWidth = true;
    }
    if (config.height && config.height !== 'auto') {
        wcfg.height = config.height;
    } else {
        wcfg.autoHeight = true;
        if (!('show' in wcfg.listeners)) wcfg.listeners.show = function() { this.center(); }
    }
    if ('tbar' in config) wcfg.tbar = config.tbar;
    var dialog = new Ext.Window(wcfg);
    if (be) {
        var btnState = function() {
            for (var i in be) {
                if (typeof be[i] === 'function') continue;
                var rules = be[i];
                if (!rules) continue;
                var btn = Ext.getCmp(i);
                if (!btn) continue;
                var form = btn.form.getForm();
                enabled = true;
                for (var j = 0; j < rules.length; j++) {
                    var o = rules[j];
                    if (!o) continue;
                    if (typeof o === 'string') {
                        var f = form.findField(o);
                        if (!f) {alert("field '"+o+"' not found"); continue; }
                        var v = f.getRawValue() || f.getValue();
                        if (!v || !f.isValid()) {
                            enabled = false;
                            break;
                        }
                    } else if (o.length) {
                        var ok = false;
                        for (var k = 0; k < o.length; k++) {
                            var r = o[k];
                            if (!r || typeof o !== 'string') continue;
                            var f = form.findField(r);
                            if (!f) {alert("field '"+r+"' not found"); continue; }
                            var v = f.getRawValue() || f.getValue();
                            if (v && f.isValid()) { ok = true; break; }
                        }
                        if (!ok) { enabled = false; break; }
                    }
                }
                btn.setDisabled(!enabled);
            }
            return true;
        }
        panel.items.each(function(item, idx, total) {
            var xt = item.getXType();
            if (xt != 'textfield' && xt != 'textarea') return;
            item.on('keypress', btnState, item, { buffer: 1200 });
            item.on('change', btnState);
        });
    }
    for (var i = 0; i < btns.length; i++) { /*btns[i].dialog = dialog;*/ btns[i].form = panel; }
    dialog.show();
    if (btnState) btnState();
};
window.Documena.fn.formQTip = function(){
    var qt = this.qtip;
    if (!qt) return;
    Ext.QuickTips.register({ target: this, title: '', text: qt, enabled: true, showDelay: 0 });
    var xt = this.getXType();
    var wrapDiv = this.getEl().up(xt == 'checkbox' ? 'div.x-form-check-wrap' : 'div.x-form-item');
    if (wrapDiv) {
        var label = wrapDiv.child('label');
        if (label) Ext.QuickTips.register({ target: label, title: '', text: qt, enabled: true });
    }
};
Ext.sequence(Ext.form.Field.prototype, 'afterRender', window.Documena.fn.formQTip);
Ext.sequence(Ext.form.Label.prototype, 'afterRender', window.Documena.fn.formQTip);

window.Documena.fn.multiselectResizer = function(id, opts) {
    var o = opts || {};
    var tbar = o.tbar || false;
    var bbar = o.bbar || false;
    var chain = typeof o.chainHandler === 'function' ? o.chainHandler : null;
    var doubleResize = false;
    var hFix1 = (o.outerHeight || 0) + 23 + (tbar ? 22 : 0) + (bbar ? 22 : 0);
    var hFix2 = (BrVer.isMSIE ? 19 + (tbar ? 22 : 0) + (bbar ? 22 : 0) : 2)
    var q = '#'+id+(BrVer.isMSIE ? ' div.x-fieldset-body' : ' fieldset');
    return function(t, adjWidth, adjHeight, rawWidth, rawHeight) {
        if (doubleResize) return;
        doubleResize = true;
        var m = Ext.getCmp(id);
        if (!m || !m.fromMultiselect || !m.toMultiselect) {
            doubleResize = false;
            return;
        }
        var w = Math.floor((adjWidth-20-20)/2);
        var h = adjHeight - hFix1 - (BrVer.isMSIE ? 15 : BrVer.isOpera ? 10 : 0);
        m.fromMultiselect.setWidth(w+1);
        m.fromMultiselect.fs.setWidth(w);
        m.fromMultiselect.setHeight(h+1);
        m.fromMultiselect.fs.setHeight(h);
        m.toMultiselect.setHeight(h+1);
        m.toMultiselect.fs.setHeight(h);
        m.toMultiselect.setWidth(w);
        m.toMultiselect.fs.setWidth(w-5);
        if (chain) 
            chain(t, adjWidth, adjHeight, rawWidth, rawHeight, m, id, w);
        var fixH = h - hFix2 + 'px';
        Ext.each(Ext.query(q), function(e) {
            var el = Ext.get(e);
            if (el) el.setHeight(fixH);
            return true;
        });
        doubleResize = false;
    }
}
