var Famark = Famark || {};
Famark._invalidElement = 'invalid element';
Famark.pageLoad = function () {
    Famark._divTools = document.getElementById('divTools');
    Famark._tblHeader = document.getElementById('tblHeader');
    Famark._divData = document.getElementById('divData');
    Famark._tblData = document.getElementById('tblData');
    Famark._txtSearch = document.getElementById('txtSearch');
    Famark._spanCount = document.getElementById('spanCount');
    Famark._getCustomRecordDisplay = null;
    Famark._dataTabElement = null;

    Famark.initButton('btnAdd', 'add', Famark.addClicked, '1');
    Famark.initButton('btnEdit', 'edit', Famark.editClicked, '2');
    Famark.initButton('btnProp', 'properties', Famark.propClicked, '3');
    Famark.initButton('btnDel', 'delete', Famark.delClicked, '4');
    Famark.initButton('btnRef', 'refresh', Famark.getFreshData, '5');
    Famark.initButton('btnMore', 'more actions', Famark.moreClicked, '6');
    Famark.initButton('btnPick', 'pick selected', Famark.pickClicked, '7');

    if (Famark._txtSearch != null) {
        Famark._txtSearch.setAttribute('data-akey', '/');
        Famark._txtSearch.title = 'search';
        Famark.addHandler(Famark._txtSearch, 'keypress', Famark.searchKeyPress);

        var btnSearch = document.getElementById('btnSearch');
        if (btnSearch != null) {
            btnSearch.title = 'search (alt + /)';
            Famark.addHandler(btnSearch, 'click', Famark.getFreshData);
        }
    }

    var entity = Famark._divData.getAttribute('data-entity');
    var viewMode = Famark._divData.getAttribute('data-mode');
    var viewTools = Famark._divData.getAttribute('data-tools');
    var ddSelector = document.getElementById('ddSelector');

    if (ddSelector != null) {
        ddSelector.setAttribute('data-akey', ';');
        ddSelector.title = 'view';
        ddSelector.value = Famark._divData.getAttribute('data-view');
        ddSelector.onchange = function () {
            var key = entity + '.view.';
            var url = Famark.setQueryParam(document.location.href, 'view', ddSelector.value);

            if (viewMode != '') {
                key += viewMode;
                url = Famark.setQueryParam(url, 'mode', viewMode);
            }

            if (viewTools != '')
                url = Famark.setQueryParam(url, 'tools', viewTools);

            Famark.setCookie(key, ddSelector.value, 60);

            var filter = Famark._divData.getAttribute('data-filter');
            if (filter != '') {
                url = Famark.setQueryParam(url, 'filter', window.encodeURIComponent(filter));
                var filterLabel = Famark._divData.getAttribute('data-filterLabel');
                if (filterLabel != null)
                    Famark.setCookie('filterLabel', filterLabel, 1);
            }

            window.location.replace(url);
        };
    }

    Famark.relatedViewShifted = function (url, filterLabel) {
        if (Famark._recordTitle !== undefined && Famark._recordTitle != null)
            filterLabel = '<b>' + Famark._recordTitle + '</b><i>' + filterLabel + '</i>';
        Famark.showFilterLabel(filterLabel);
        Famark.setCookie('filterLabel', filterLabel, 1);
        window.location.replace(url);
    };

    Famark.addHandler(window, 'resize', Famark.screenLoad);
    Famark.addHandler(window, 'focus', Famark.addAccessKey);
    Famark.addHandler(window, 'blur', Famark.removeAccessKey);
    Famark.addHandler(Famark._divData, 'scroll', Famark.conScroll);

    if (Famark._tblHeader != null) {
        Famark._tblHeader.style.cursor = 'pointer';

        Famark._tblHeader.onclick = function (e) {
            e = e || window.event;
            var el = e.target || e.srcElement;

            while (el.nodeName != 'TD' && el.nodeName != 'BODY')
                el = el.parentNode;

            if (el.nodeName == 'BODY') return;

            var newOrder = el.getAttribute('data-field');
            var lastOrder = Famark._divData.getAttribute('data-orderBy');

            if (lastOrder == newOrder)
                newOrder += ' Desc';

            var key = entity + '.orderBy.' + Famark._divData.getAttribute('data-view') + '.';

            if (viewMode != '')
                key += viewMode;

            Famark.setCookie(key, newOrder, 60);

            Famark._divData.setAttribute('data-orderBy', newOrder);
            Famark.getFreshData();
        };

        if (Famark._tblData != null) {//set resizing
            Famark._tblHeader.dragging = null;

            Famark.addHandler(Famark._tblHeader, 'mousedown', function () {
                if (Famark._tblHeader.moving != null) {
                    Famark._tblHeader.dragging = Famark._tblHeader.moving;
                    Famark._tblHeader.totalWidth = Famark._tblHeader.dragging.clientWidth + Famark._tblHeader.dragging.nextSibling.clientWidth;
                    Famark._tblHeader.moving = null;
                    Famark._tblHeader.stopclick = Famark._tblHeader.onclick;
                    Famark._tblHeader.onclick = null;
                }
            });

            Famark.addHandler(Famark._tblHeader, 'mouseup', function () {
                if (Famark._tblHeader.dragging != null) {
                    Famark._tblHeader.dragging = null;
                    Famark._tblHeader.totalWidth = null;
                    var tdTops = Famark._tblHeader.getElementsByTagName('tr')[0].getElementsByTagName('td');
                    var tdCons = Famark._tblData.getElementsByTagName('tr')[0].getElementsByTagName('td');
                    for (var i = 0; i < tdCons.length; i++) {
                        tdCons[i].style.width = tdTops[i].style.width; // +'px';
                    }
                    window.setTimeout(function () { Famark._tblHeader.onclick = Famark._tblHeader.stopclick; Famark._tblHeader.stopclick = null; }, 20);
                }
            });

            Famark.addHandler(Famark._tblHeader, 'mousemove', Famark.colResize);
        } else {//no tblData means ul prop view
            Famark.makeSelectHeader(Famark._tblHeader);
        }
    }

    if (viewMode != 'Properties') {
        Famark.onRowDoubleClick = viewMode == 'Select' ? Famark.selectRecord : Famark.showEditForm;

        if (Famark._tblData != null) {
            Famark.addHandler(Famark._tblData, 'click', Famark.rowClicked);
            Famark.addHandler(Famark._tblData, 'dblclick', Famark.rowDoubleClicked);
        }
        else {
            Famark.addHandler(Famark._divData, 'click', Famark.rowClicked);
            Famark.addHandler(Famark._divData, 'dblclick', Famark.rowDoubleClicked);
        }
        Famark.addHandler(document, 'keydown', Famark.docKeyDown);
    }

    Famark.screenLoad();
    Famark.showCount();
    Famark.showFilterLabelFromCookie();
    Famark.setDataTabIndex();

    if (!Famark.loadView) {
        alert('Error in view script.');
        return;
    }

    Famark.loadView();

    var container = Famark._divData.firstChild;
    if (container.firstChild != null && container.firstChild.nodeName == 'TBODY')
        container = container.firstChild;

    Famark.clientFormatDateTime(container, 0);

    if (Famark._cellFormatIndex.length > 0)
        Famark.formatCells(container, 0, container.childNodes.length);
    if (Famark.pageChanged)
        Famark.pageChanged(container, 0, container.childNodes.length);
};

Famark.setQueryParam = function (url, paramName, paramValue) {
    var pattern = new RegExp('\\b(' + paramName + '=).*?(&|#|$)');
    if (url.search(pattern) >= 0) {
        return url.replace(pattern, '$1' + paramValue + '$2');
    }
    url = url.replace(/[?#]$/, '');
    return url + (url.indexOf('?') > 0 ? '&' : '?') + paramName + '=' + paramValue;
};

Famark.makeSelectHeader = function (tblHeader) {
    /*surround the header table with a "select-header" DIV element.*/
    var divHeader = document.createElement("DIV");
    divHeader.id = "divHeader";
    divHeader.className = "select-header";

    tblHeader.parentNode.insertBefore(divHeader, tblHeader);
    tblHeader.parentNode.removeChild(tblHeader);
    divHeader.appendChild(tblHeader);

    /*for each element, create a new DIV that will act as the selected item:*/
    var topDiv = document.createElement("DIV");
    topDiv.setAttribute("class", "select-selected");

    var orderBy = document.getElementById("divData").getAttribute("data-orderby");
    var sPos = orderBy.indexOf(' ');
    if (sPos > 0)
        orderBy = orderBy.substr(0, sPos);
    var tdOrder = tblHeader.querySelector("td[data-field='" + orderBy + "']");
    topDiv.innerHTML = tdOrder.innerHTML;
    divHeader.appendChild(topDiv);
    var allHeadItems = tblHeader.querySelectorAll("td");

    /*for each element, create a new DIV that will contain the option list:*/
    var listBox = document.createElement("DIV");
    listBox.setAttribute("class", "select-items select-hide");
    for (var i = 0; i < allHeadItems.length; i++) {
        /*for each option in the original select element,
        create a new DIV that will act as an option item:*/
        var item = document.createElement("DIV");
        item.innerHTML = allHeadItems[i].innerHTML;
        item.addEventListener("click", function (e) {
            /*when an item is clicked, update the original select box,
            and the selected item:*/
            for (var j = 0; j < allHeadItems.length; j++) {
                if (allHeadItems[j].innerHTML == this.innerHTML) {
                    topDiv.innerHTML = this.innerHTML;
                    var lastSelected = this.parentNode.getElementsByClassName("same-as-selected");
                    for (var k = 0; k < lastSelected.length; k++) {
                        lastSelected[k].removeAttribute("class");
                    }
                    this.setAttribute("class", "same-as-selected");
                    Famark.triggerClick(allHeadItems[j]);
                    break;
                }
            }
            topDiv.click();
        });
        listBox.appendChild(item);
    }

    divHeader.appendChild(listBox);

    topDiv.addEventListener("click", function (e) {
        /*when the select box is clicked, close any other select boxes,
        and open/close the current select box:*/
        e.stopPropagation();
        closeAllSelect(this);
        this.nextSibling.classList.toggle("select-hide");
        this.classList.toggle("select-arrow-active");
    });

    function closeAllSelect(el) {
        /*a function that will close all select boxes in the document,
        except the current select box:*/
        var x, y, i, arrNo = [];
        x = document.getElementsByClassName("select-items");
        y = document.getElementsByClassName("select-selected");
        for (i = 0; i < y.length; i++) {
            if (el == y[i]) {
                arrNo.push(i)
            } else {
                y[i].classList.remove("select-arrow-active");
            }
        }
        for (i = 0; i < x.length; i++) {
            if (arrNo.indexOf(i)) {
                x[i].classList.add("select-hide");
            }
        }
    }
    /*if the user clicks anywhere outside the select box,
    then close all select boxes:*/
    document.addEventListener("click", closeAllSelect);
};

Famark.initButton = function (btnId, title, handler, accessKey) {
    var btn = document.getElementById(btnId);
    if (btn != null) {
        btn.title = title;
        btn.setAttribute('data-akey', accessKey);
        Famark.addHandler(btn, 'click', handler);
    }
};

Famark.addAccessKey = function () {
    Famark.toggleAccessKey('data-akey', 'accesskey', Famark.addTitleAlt);
};

Famark.removeAccessKey = function () {
    Famark.toggleAccessKey('accesskey', 'data-akey', Famark.removeTitleAlt);
};

Famark.addTitleAlt = function (title, bPos, akey) { return (bPos == -1) ? title + ' (alt + ' + akey + ')' : title; };
Famark.removeTitleAlt = function (title, bPos, akey) { return (bPos > 0) ? title.substr(0, bPos - 1) : title; };

Famark.toggleAccessKey = function (fromAttr, toAttr, getTitle) {
    var els = document.querySelectorAll('[' + fromAttr + ']:not([' + fromAttr + '=""])');
    for (var i = 0; i < els.length; i++) {
        var el = els[i];
        var akey = el.getAttribute(fromAttr);
        el.setAttribute(toAttr, akey);
        el.removeAttribute(fromAttr);
        var bPos = (el.title != null) ? el.title.indexOf('(') : -10;
        el.title = getTitle(el.title, bPos, akey);
    }
};
Famark.showCount = function () {
    if (Famark._spanCount != null) {
        var total = Famark.getCookie('totalCount');
        if (total != null) {
            Famark._spanCount.innerHTML = total;
            Famark.setCookie('totalCount', '', -1);
        }
    }
};

Famark.showFilterLabelFromCookie = function () {
    var filterLabel = Famark.getCookie('filterLabel');
    if (filterLabel != null) {
        var filter = Famark._divData.getAttribute('data-filter');
        if (filter != '')
            Famark.showFilterLabel(filterLabel);
        Famark.setCookie('filterLabel', '', -1);
    }
};

Famark.showFilterLabel = function (label) {
    var h3Title = document.getElementById('h3Title');
    if (h3Title != null) {
        h3Title.innerHTML = label;
    }
    Famark._divData.setAttribute('data-filterLabel', label);
};

Famark._cellFormatIndex = [];
Famark._cellFormatters = [];

Famark.setFormatter = function (field, cellFormatter, headerFormatter) {
    if (Famark._tblHeader != null && Famark._tblHeader.firstChild != null) {
        var headerRow = Famark._tblHeader.firstChild;
        if (headerRow != null && headerRow.nodeName == 'TBODY')
            headerRow = headerRow.firstChild;
        for (var i = 0; i < headerRow.childNodes.length; i++) {
            var headerCell = headerRow.childNodes[i];
            if (headerCell.getAttribute('data-field') == field) {
                Famark._cellFormatIndex.push(i);
                Famark._cellFormatters.push(cellFormatter);
                if (headerFormatter != null)
                    headerFormatter(headerCell);
                break;
            }
        }
    }
};

Famark.formatCells = function (container, index, count) {
    for (var r = index; r < index + count; r++) {
        var row = container.childNodes[r];
        for (var c = 0; c < Famark._cellFormatIndex.length; c++)
            Famark._cellFormatters[c](row.childNodes[Famark._cellFormatIndex[c]]);
    }
};

Famark.setTextAlign = function (field, align, padding) {
    if (align != null) {
        var aligner;
        if (padding == null)
            aligner = function (cell) { cell.style.textAlign = align; };
        else if (align.toUpperCase() == 'RIGHT')
            aligner = function (cell) { cell.style.textAlign = align; cell.style.paddingRight = padding; };
        else if (align.toUpperCase() == 'LEFT')
            aligner = function (cell) { cell.style.textAlign = align; cell.style.paddingLeft = padding; };
        else //'CENTER'
            aligner = function (cell) { cell.style.textAlign = align; };
        Famark.setFormatter(field, aligner, aligner);
    }
};

Famark.getRowElement = function (target) {
    while (target.nodeName != 'TR' && target.nodeName != 'UL' && target.nodeName != 'BODY')
        target = target.parentNode;
        if (target.nodeName == 'BODY' || target.className == 'deleted')
            return null;
        if (target.id != null && target.id.length == 36)
            return target;
    return Famark.getRowElement(target.parentNode);
};

Famark.docKeyDown = function (e) {
    e = e || window.event;
    if (Famark._dataTabElement == null || (e.keyCode != 13 && e.keyCode != 38 && e.keyCode != 40))
        return;
    var row = Famark._divData.querySelector('[outline]');
    if (row == null) {
        if (e.ctrlKey)
            Famark._dataTabElement.focus();
        return;
    }
    if (e.keyCode == 13) {
        Famark.triggerClick(row);
        return;
    }
    var newRow = null;
    if (e.keyCode == 40 && row.nextSibling != null)
        newRow = row.nextSibling;
    else if (e.keyCode == 38 && row.previousSibling != null && row.previousSibling.getAttribute('data-collapsed') != 'true')
        newRow = row.previousSibling;
    if (newRow != null) {
        row.removeAttribute('outline');
        newRow.setAttribute('outline', '1');
        Famark.scrollIntoView(newRow, Famark._divData);
        e.preventDefault();
    }
};

Famark.scrollIntoView = function (target, container) {
    var eRect = target.getBoundingClientRect();
    var cRect = container.getBoundingClientRect();
    
    if (eRect.bottom > cRect.bottom)
        target.scrollIntoView(false);
    else if (eRect.top < cRect.top)
        target.scrollIntoView(true);
};

Famark.rowClicked = function (e) {
    e = e || window.event;
    var target = Famark.getRowElement(e.target || e.srcElement);
    if (target == null)
        return;

    var selId = Famark._divData.getAttribute('data-selected');
    var tds, i, j;

    function resetHighlight(row) {
        row.className = row.lastClassName;
        if (row.nodeName != 'TR')
            return;
        tds = row.getElementsByTagName('td');
        for (j = 0; j < tds.length; j++) {
            if (tds[j].lastClassName !== undefined) {
                tds[j].className = tds[j].lastClassName;
                return;
            }
        }
    }

    function setHighlight(row) {
        row.lastClassName = row.className;
        row.className = row.className.indexOf(' updated') < 0 ? 'selected' : 'selected updated';
        if (row.nodeName != 'TR')
            return;
        tds = row.getElementsByTagName('td');
        for (j = 0; j < tds.length; j++) {
            if (tds[j].className == 'ch1' || tds[j].className == 'ch2') {
                tds[j].lastClassName = tds[j].className;
                tds[j].className = '';
                break;
            }
        }
    }

    var lr, tr;
    if (e.ctrlKey == 1 && selId != null && selId != '') {
        var selPos = selId.indexOf(target.id);
        if (selPos > -1) {
            var nextPos = selId.indexOf(',', selPos + 1);
            if (nextPos < 0)
                selId = selId.substring(0, selPos - 1);
            else
                selId = selId.substring(0, selPos) + selId.substring(nextPos + 1);

            resetHighlight(target);
            Famark._divData.setAttribute('data-selected', selId);
            return;
        }

        selId = selId + ',' + target.id;
    }
    else if (e.shiftKey == 1 && selId != null && selId != '') {
        lr = selId.split(',');
        for (i = 0; i < lr.length; i++) {
            tr = document.getElementById(lr[i]);
            resetHighlight(tr);
        }

        var sib = document.body.previousElementSibling ? 'previousElementSibling' : 'previousSibling';
        var rI;
        function getRowIndex(row) {
            rI = 0;
            while ((row = row[sib]) != null)
                rI++;
            return rI;
        }

        var rows = target.parentNode.childNodes;
        var lastPos = selId.lastIndexOf(',');
        var lastRowIndex = getRowIndex(document.getElementById(selId.substring(lastPos + 1)));
        selId = '';
        var newRowIndex = getRowIndex(target);
        if (newRowIndex > lastRowIndex) {
            for (rI = lastRowIndex; rI < newRowIndex; rI++) {
                setHighlight(rows[rI]);
                selId += rows[rI].id + ',';
            }
        }
        else if (lastRowIndex > newRowIndex) {
            for (rI = lastRowIndex; rI > newRowIndex; rI--) {
                setHighlight(rows[rI]);
                selId += rows[rI].id + ',';
            }
        }

        selId += target.id;
        Famark.clearSelection();
    }
    else {
        if (selId != null && selId != '') {
            lr = selId.split(',');
            for (i = 0; i < lr.length; i++) {
                tr = document.getElementById(lr[i]);
                resetHighlight(tr);
            }
        }
        selId = target.id;
        Famark._recordTitle = Famark._getCustomRecordDisplay != null ? Famark._getCustomRecordDisplay(target) : target.firstChild.innerHTML;

        var dataMode = Famark._divData.getAttribute('data-mode');
        if (dataMode != 'Related' && dataMode != 'Select' && window.top.Famark != null && window.top.Famark.viewRecordSelected != null) {
            var nowTicks = new Date().getTime();
            if (Famark._lastSelectTime === undefined || Famark._lastSelectTime < (nowTicks - 250)) {
                Famark._lastSelectTime = nowTicks;
                window.top.Famark.viewRecordSelected(Famark._divData.getAttribute('data-entity'), selId, Famark._recordTitle);
            }
        }
    }

    setHighlight(target);
    Famark.setDataTabIndexOnRow(target);
    Famark.setOutline(target);
    target.focus();
    Famark._divData.setAttribute('data-selected', selId);
};

Famark.rowDoubleClicked = function (e) {
    e = e || window.event;
    var target = Famark.getRowElement(e.target || e.srcElement);
    if (target == null)
        return;
    
    //prevent selection on dblclick
    Famark.clearSelection();

    var selId = Famark._divData.getAttribute('data-selected');
    if (selId == null || selId == '')
        return;
    var cPos = selId.lastIndexOf(',');
    selId = (cPos > 0) ? selId.substring(cPos + 1) : selId;
    Famark.onRowDoubleClick(selId);
};

Famark.showEditForm = function (selId) {
    var url = Famark.getFormUrlPrefix() + '&rid=' + selId;
    var win = window.top.Famark.showWindow(url);
    win.opener = Famark._dataTabElement;
};

Famark.showProperties = function (selId) {
    var url = 'Prop.ashx?entity=' + Famark._divData.getAttribute('data-entity') + '&mode=1&rid=' + selId;
    var win = window.top.Famark.showWindow(url);
    win.opener = Famark._dataTabElement;
};

Famark.selectRecord = function (selId) {
    Famark._divData.setAttribute('data-selected', selId);
    Famark.pickClicked();
};

Famark.getViewMode = function () {
    var mode = Famark._divData.getAttribute('data-mode');
    return (mode == '') ? 'MAIN' : mode.toUpperCase();
};
Famark.getViewInfo = function () {
    var mode = Famark._divData.getAttribute('data-mode');
    var viewInfo = {};
    viewInfo.viewMode = (mode == '') ? 'MAIN' : mode.toUpperCase();
    viewInfo.entityName = Famark._divData.getAttribute('data-entity');
    viewInfo.viewName = Famark._divData.getAttribute('data-view');
    viewInfo.filter = Famark._divData.getAttribute('data-filter');
    return viewInfo;
};

Famark.setFormName = function (formName) {
    Famark._divData.setAttribute('data-formName', formName);
};
Famark.setFormTools = function (formTools) {
    Famark._divData.setAttribute('data-formTools', formTools);
};

Famark.setViewTools = function (viewTools) {
    var ddSelector = document.getElementById('ddSelector');
    var tblSearch = document.getElementById('tblSearch');
    Famark._divData.setAttribute('data-tools', viewTools);
    if (viewTools == 'hidden') {
        if (ddSelector != null)
            ddSelector.style.display = 'none';
        if (tblSearch != null)
            tblSearch.style.display = 'none';
        var divButtons = document.getElementById('divButtons');
        if (divButtons != null)
            divButtons.style.display = 'none';
        return;
    }

    var tools = viewTools.split(',');
    function hasTool(tool) {
        for (var i = 0; i < tools.length; i++) {
            if (tools[i] == tool)
                return true;
        }
        return false;
    }

    if (ddSelector != null)
        ddSelector.style.display = hasTool('selector') ? 'auto' : 'none';

    if (tblSearch != null)
        tblSearch.style.display = hasTool('search') ? 'auto' : 'none';

    if (Famark._spanCount != null)
        Famark._spanCount.style.display = hasTool('count') ? 'auto' : 'none';

    var btnAdd = document.getElementById('btnAdd');
    if (btnAdd != null)
        btnAdd.style.display = hasTool('add') ? 'auto' : 'none';

    var btnEdit = document.getElementById('btnEdit');
    if (btnEdit != null)
        btnEdit.style.display = hasTool('edit') ? 'auto' : 'none';

    var btnProp = document.getElementById('btnProp');
    if (btnProp != null)
        btnProp.style.display = hasTool('prop') ? 'auto' : 'none';

    var btnDel = document.getElementById('btnDel');
    if (btnDel != null)
        btnDel.style.display = hasTool('del') ? 'auto' : 'none';

    var btnRef = document.getElementById('btnRef');
    if (btnRef != null)
        btnRef.style.display = hasTool('ref') ? 'auto' : 'none';

    var btnMore = document.getElementById('btnMore');
    if (btnMore != null)
        btnMore.style.display = hasTool('more') ? 'auto' : 'none';

    var btnPick = document.getElementById('btnPick');
    if (btnPick != null)
        btnPick.style.display = hasTool('pick') ? 'auto' : 'none';
};

Famark.setRecordDisplayFunction = function (fn) {
    Famark._getCustomRecordDisplay = fn;
};

Famark.getFormUrlPrefix = function () {
    var url = 'Form.ashx?entity=' + Famark._divData.getAttribute('data-entity');
    var formName = Famark._divData.getAttribute('data-formName');
    if (formName != null && formName != '')
        url += '&form=' + formName;

    var formTools = Famark._divData.getAttribute('data-formTools');
    if (formTools != null && formTools != '')
        url += '&tools=' + formTools;

    var filter = Famark._divData.getAttribute('data-filter');
    if (filter != null && filter != '')
        url += '&preset=' + window.encodeURIComponent(filter);
    return url;
};

Famark.addClicked = function () {
    var url = Famark.getFormUrlPrefix();
    var win = window.top.Famark.showWindow(url);
    win.opener = document.getElementById('btnAdd');
};
Famark.editClicked = function () {
    var selId = Famark._divData.getAttribute('data-selected');
    if (selId == null || selId == '')
        return;

    var url = Famark.getFormUrlPrefix() + '&rid=' + selId;
    if (url.length > 2000) {
        alert('Cannot bulk edit more than 50 records.');
        return;
    }
    var win = window.top.Famark.showWindow(url);
    win.opener = document.getElementById('btnEdit');
};
Famark.propClicked = function () {
    var selId = Famark._divData.getAttribute('data-selected');
    if (selId == null || selId == '')
        return;
    var cPos = selId.lastIndexOf(',');
    selId = (cPos > 0) ? selId.substring(cPos + 1) : selId;

    var target = document.getElementById(selId);
    var title = Famark._getCustomRecordDisplay != null ? Famark._getCustomRecordDisplay(target) : target.firstChild.innerHTML;
    var url = 'Prop.ashx?entity=' + Famark._divData.getAttribute('data-entity') + '&mode=1&rid=' + selId;
    var win = window.top.Famark.showWindow(url);
    win.opener = document.getElementById('btnProp');
    win.setContentHeight(600);
    win.setTitle(title);
};
Famark.delClicked = function () {
    var selId = Famark._divData.getAttribute('data-selected');
    if (selId == null || selId == '')
        return false;

    if (!Famark.deletingRecord) {
        alert('Error in view script.');
        return false;
    }

    var proceed = Famark.deletingRecord();
    if (proceed !== undefined && !proceed)
        return false;

    if (!confirm('Press Ok to confirm deleting selected record(s).'))
        return false;

    var data = 'entity=' + Famark._divData.getAttribute('data-entity') +
            '&work=DeleteRecord&rid=' + selId;

    var http = new XMLHttpRequest();
    http.open('POST', 'Work.ashx', false);
    http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    http.send(data);
    var result = Famark.parseJSON(http.responseText);
    if (result.ErrorMessage == null || result.ErrorMessage == '') {
        Famark._divData.setAttribute('data-selected', '');
        var rids = selId.split(',');
        for (var i = 0; i < rids.length; i++) {
            var el = document.getElementById(rids[i]);
            if (el != null)
                el.className = 'deleted';
        }
        return true;
    }

    alert(result.ErrorMessage);
    return false;
};
Famark.moreClicked = function () {
    var url = 'More.ashx?entity=' + Famark._divData.getAttribute('data-entity');
    var selId = Famark._divData.getAttribute('data-selected');
    if (selId != null && selId != '')
        url += '&rid=' + selId;
    var filter = Famark._divData.getAttribute('data-filter');
    if(filter != null && filter != '')
        url += '&filter=' + window.encodeURIComponent(filter);
    var win = window.top.Famark.showDialog(url);
    win.opener = document.getElementById('btnMore');
};
Famark.pickClicked = function () {
    if (window.top.Famark != null && window.top.Famark.viewRecordPicked != null) {
        var selId = Famark._divData.getAttribute('data-selected');
        if (selId == null || selId == '')
            return;
        var cPos = selId.lastIndexOf(',');
        selId = (cPos > 0) ? selId.substring(cPos + 1) : selId;
        var target = document.getElementById(selId);
        var title = Famark._getCustomRecordDisplay != null ? Famark._getCustomRecordDisplay(target) : target.firstChild.innerHTML;
        window.top.Famark.viewRecordPicked(Famark._divData.getAttribute('data-entity'), selId, title);
        if (window.top.Famark.closeWindow != null)
            window.top.Famark.closeWindow(window);
        else
            window.close();
    }
};
Famark.colResize = function (e) {
    e = e || window.event;
    var x = e.clientX;

    if (Famark._tblHeader.dragging != null) {
        var cell = Famark._tblHeader.dragging;
        var newWidth = (x - cell.offsetLeft);
        if (newWidth < 1)
            newWidth = 1;
        else if (newWidth > (Famark._tblHeader.totalWidth - 1))
            newWidth = Famark._tblHeader.totalWidth - 1;

        cell.style.width = newWidth + 'px';

        var siblingWidth = Famark._tblHeader.totalWidth - newWidth;
        cell.nextSibling.style.width = siblingWidth + 'px';

        var breakCount = 0;
        while ((cell.clientWidth + cell.nextSibling.clientWidth) > Famark._tblHeader.totalWidth) {
            siblingWidth = siblingWidth - 1;
            cell.nextSibling.style.width = siblingWidth + 'px';
            if (breakCount > 100)
                break;
            breakCount++;
        }
    }
    else {

        var cells = Famark._tblHeader.getElementsByTagName('tr')[0].getElementsByTagName('td');
        Famark._tblHeader.moving = null;

        for (var i = 0; i < cells.length - 1; i++) {
            var border = cells[i].offsetLeft + cells[i].offsetWidth;
            if (x > border - 8 && x < border + 8) {
                Famark._tblHeader.style.cursor = 'w-resize';
                Famark._tblHeader.moving = cells[i];
                break;
            }
        }

        if (Famark._tblHeader.moving == null)
            Famark._tblHeader.style.cursor = 'pointer';
    }
};
Famark._resizeTimeout = null;
Famark.screenLoad = function () {
    if (Famark._resizeTimeout)
        window.clearTimeout(Famark._resizeTimeout);
    Famark._resizeTimeout = window.setTimeout(function() {
        Famark.resetCellWidth(Famark._tblHeader);
        Famark.resetCellWidth(Famark._tblData);

        Famark.resizeTools(20);
        window.setTimeout(function() {
            var newHeight = document.body.clientHeight - Famark._divData.offsetTop;
            if (newHeight < 0)
                newHeight = 0;
            Famark._divData.style.height = newHeight + 'px';
        }, 40);
        Famark.resizeTools(80);

        var forms = Famark.getElementsByClassName('divWin', 'div');
        for (var i = 0; i < forms.length; i++)
            forms[i].rePosition();
        Famark._resizeTimeout = null;
    }, 100);
};
Famark.resetCellWidth = function (tbl) {
    if (tbl != null) {
        var tdHeader = tbl.getElementsByTagName('tr')[0].getElementsByTagName('td');
        for (var i = 0; i < tdHeader.length; i++) {
            tdHeader[i].style.width = '';
        }
        tbl.style.width = '100%';
    }
};
Famark.conScroll = function () {
    if (Famark._divData.lastScrollTop === undefined || Famark._divData.scrollTop != Famark._divData.lastScrollTop) {
        if (Famark._divData.scrollTop <= 0) {
            //alert('top');
        }
        else if (Famark._divData.scrollTop >= (Famark._divData.scrollHeight - Famark._divData.clientHeight - 1)) {
            Famark.appendData();
        }
        Famark._divData.lastScrollTop = Famark._divData.scrollTop;
    }
};
Famark.searchKeyPress = function (e) {
    e = e || window.event;
    if (e.keyCode == 13)
        Famark.getFreshData();
};
Famark.setDataTabIndex = function () {
    var container = Famark._divData.firstChild;
    if (container.firstChild != null && container.firstChild.nodeName == 'TBODY')
        container = container.firstChild;
    var firstNode = container.firstChild;
    if (firstNode != null && firstNode.nodeType == 1 && firstNode.getAttribute('data-collapsed') == 'true')
        firstNode = firstNode.nextSibling;
    Famark.setDataTabIndexOnRow(firstNode);
};
Famark.setDataTabIndexOnRow = function (row) {
    if (Famark._dataTabElement != null) {
        var lastTabElement = Famark._dataTabElement;
        lastTabElement.tabIndex = -1;
        lastTabElement.onfocus = null;
        lastTabElement.onblur = null;
    }
    if (row != null) {
        row.tabIndex = 0;
        row.onfocus = function () { Famark.setOutline(row); };
        row.onblur = function () { Famark.setOutline(null); };
    }
    Famark._dataTabElement = row;
};
Famark.setOutline = function (row) {
    var lastOutline = Famark._divData.querySelector('[outline]');
    if (lastOutline != null)
        lastOutline.removeAttribute('outline');
    if (row != null)
        row.setAttribute('outline', '1');
};
Famark.getFreshData = function () {
    Famark._divData.setAttribute('data-selected', '');
    Famark._divData.setAttribute('data-pageIndex', '-1');
    Famark._divData.setAttribute('data-hasMore', 'TRUE');

    var container = Famark._divData.firstChild;
    if (container.firstChild != null && container.firstChild.nodeName == 'TBODY')
        container = container.firstChild;

    while (container.childNodes.length > 1)
        container.removeChild(container.lastChild);

    var firstNode = container.firstChild;
    if (firstNode != null && (firstNode.nodeType != 1 || firstNode.getAttribute('data-collapsed') != 'true'))
        container.removeChild(firstNode);

    Famark.appendData();
    Famark.showCount();
    Famark.setDataTabIndex();
    Famark.resizeTools(20);
    Famark._divData.scrollTop = 0;
};
Famark.resizeTools = function (timeOut) {
    if (Famark._divTools != null)
        window.setTimeout(function () { if(Famark._divData.clientWidth > 0) Famark._divTools.style.width = Famark._divData.clientWidth + 'px'; }, timeOut);
};
Famark.appendData = function () {
    if (Famark._divData.getAttribute('data-hasMore') == 'FALSE')
        return;

    var url = 'View.ashx?entity=' + Famark._divData.getAttribute('data-entity') +
        '&view=' + Famark._divData.getAttribute('data-view') +
        '&filter=' + window.encodeURIComponent(Famark._divData.getAttribute('data-filter')) +
        '&root=' + Famark._divData.firstChild.nodeName;

    var pageSize = parseInt(Famark._divData.getAttribute('data-pageSize'));
    var isPropMode = isNaN(pageSize);//In Properties mode pageSize = '' but getFreshData resets hasMore and pageIndex

    if (isPropMode) {
        url += '&mode=' + Famark._divData.getAttribute('data-mode');
    } else {
        var pageIndex = parseInt(Famark._divData.getAttribute('data-pageIndex')) + 1;
        Famark._divData.setAttribute('data-pageIndex', pageIndex);
        url += '&orderBy=' + Famark._divData.getAttribute('data-orderBy') +
            '&pageSize=' + pageSize + '&pageIndex=' + pageIndex;
    }

    if (Famark._txtSearch != null && Famark._txtSearch.value != '') {
        url += '&search=' + window.encodeURIComponent(Famark._txtSearch.value) +
        '&searchFields=' + Famark._divData.getAttribute('data-searchFields');
    }

    var http = new XMLHttpRequest();
    http.open("GET", url, false);
    http.send();
    var data = document.createElement('div');
    data.innerHTML = http.responseText;
    data = data.firstChild;

    if (data.firstChild != null && data.firstChild.nodeName == 'TBODY')
        data = data.firstChild;

    var resultCount = data.childNodes.length;

    if (isPropMode || resultCount < pageSize)
        Famark._divData.setAttribute('data-hasMore', 'FALSE');

    var container = Famark._divData.firstChild;
    if (container.firstChild != null && container.firstChild.nodeName == 'TBODY')
        container = container.firstChild;

    if (resultCount > 0) {
        var index = container.childNodes.length;
        while (data.childNodes.length > 0)
            container.appendChild(data.firstChild);
        Famark.clientFormatDateTime(container, index);

        if (Famark._cellFormatIndex.length > 0)
            Famark.formatCells(container, index, resultCount);
        if (Famark.pageChanged)
            Famark.pageChanged(container, index, resultCount);
    }
};
Famark.viewRecordPicked = function (entity, rid, title) {
    var frames = window.frames;
    for (var i = 0; i < frames.length; i++) {
        if (frames[i].Famark != null && frames[i].Famark.viewRecordPicked != null)
            frames[i].Famark.viewRecordPicked(entity, rid, title);
    }
};
Famark.formRecordCreated = function (entity, rid, data) {
    if (Famark._divData.getAttribute('data-entity') == entity) {
        Famark.getFreshData();
        var row = document.getElementById(rid);
        if (row)
            Famark.triggerClick(row);
    }
    //for props in dialog    
    var frames = window.frames;
    for (var i = 0; i < frames.length; i++) {
        if (frames[i].Famark != null && frames[i].Famark.formRecordCreated != null)
            frames[i].Famark.formRecordCreated(entity, rid, data);
    }
};
Famark.formRecordUpdated = function (entity, rid, data) {
    if (Famark._divData.getAttribute('data-entity') == entity) {
        var rids = rid.split(',');
        for (var r = 0; r < rid.length; r++) {
            var tr = document.getElementById(rids[r]);
            if (tr != null) {
                tr.className += ' updated';
                tr.lastClassName += ' updated';
            }
        }
    }

    var frames = window.frames;
    for (var i = 0; i < frames.length; i++) {
        if (frames[i].Famark != null && frames[i].Famark.formRecordUpdated != null)
            frames[i].Famark.formRecordUpdated(entity, rid, data);
    }
};

Famark.triggerClick = function (el) {
    var evt;
    if (document.createEvent) {
        // dispatch for firefox + others
        evt = document.createEvent("HTMLEvents");
        evt.initEvent('click', true, true); // event type,bubbling,cancelable
        return el.dispatchEvent(evt);
    }
    else {
        // dispatch for IE
        evt = document.createEventObject();
        return el.fireEvent('onclick', evt);
    }
};

Famark.makeHtmlDisplay = function (el) {
    if (el == null || el.innerHTML === undefined) {
        alert(Famark._invalidElement);
        return;
    }

    var i = 0, node = el;
    while ((node = node.previousSibling) != null)
        i++;
    node = el;
    while (node && (node.id === undefined || node.id == ''))
        node = node.parentNode;

    var hdId = 'if_' + i + '_' + (!node ? '' : node.id);

    function writeContent() {
        var hd = new Caja.HtmlDisplay(hdId);
        hd.html = el.innerHTML.replace(/&gt;/g, '>').replace(/&lt;/g, '<').replace(/&amp;/g, '&');
        var p = document.createElement('p');
        el.parentNode.appendChild(p);
        hd.drawIn(p);
        el.style.display = 'none';
    };

    if (window.Caja !== undefined) {
        writeContent();
        return;
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'Attachment/Caja.js';

    Famark.addHandler(script, 'load', function () { writeContent(); });

    document.getElementsByTagName('head')[0].appendChild(script);
};

Famark.addHandler = function (el, ev, fn) {
    if (el.addEventListener)
        el.addEventListener(ev, fn, false);
    else if (el.attachEvent)
        el.attachEvent('on' + ev, fn);
    else
        el[ev] = fn;
};

Famark.parseJSON = function (data) {
    if (data == null || typeof data !== 'string')
        return null;

    data = (data.trim) ? data.trim() : data.replace(/^\s+|\s+$/g, '');

    if (window.JSON && window.JSON.parse)
        return window.JSON.parse(data);

    var valData = data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    valData = valData.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    valData = valData.replace(/(?:^|:|,)(?:\s*\[)+/g, '');

    var valExp = /^[\],:{}\s]*$/;

    if (valExp.test(valData))
        return (new Function('return ' + data))();

    alert('Invalid JSON: ' + data);
    return null;
};

Famark.getDisplayTime = function (hh, mm) {
    var tt = hh > 11 ? 'PM' : 'AM';
    hh = ((hh + 11) % 12) + 1;
    return (hh < 10 ? '0' : '') + hh + ':' + (mm < 10 ? '0' : '') + mm + ' ' + tt;
};

Famark.getDateFromIso = function (s) {
    var day = new Date('1980-12-21T15:25:00+05:30');
    if (isFinite(day) && day.getTime() === 346240500000)
        return new Date(s);
    var tz,
        rx = /^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
        p = rx.exec(s) || [];
    if (!p[1])
        return NaN;
    day = p[1].split(/\D/);
    for (var i = 0; i < day.length; i++)
        day[i] = parseInt(day[i], 10) || 0;
    day[1] -= 1;
    day = new Date(Date.UTC.apply(Date, day));
    if (!day.getDate())
        return NaN;
    if (p[5]) {
        tz = (parseInt(p[5], 10) * 60);
        if (p[6]) tz += parseInt(p[6], 10);
        if (p[4] == '+') tz *= -1;
        if (tz) day.setUTCMinutes(day.getUTCMinutes() + tz);
    }
    return day;
};

Famark.clientFormatDateTime = function (container, index) {
    for (var i = index; i < container.childNodes.length; i++) {
        var dts = container.childNodes[i].querySelectorAll('[data-format="datetime"]');
        for (var j = 0; j < dts.length; j++) {
            var dtVal = dts[j].innerHTML;
            if (dtVal.length < 8)
                continue;
            if (dtVal.length < 10) {
                var tps = dtVal.split(':');
                if (tps.length < 2)
                    continue;
                dts[j].innerHTML = Famark.getDisplayTime(parseInt(tps[0], 10), parseInt(tps[1], 10));
                continue;
            }
            var sPos = dtVal.indexOf(' ');
            if (sPos < 1)
                continue;
            dtVal = dtVal.substr(0, sPos) + 'T' + dtVal.substr(sPos + 1) + 'Z';
            var dt = Famark.getDateFromIso(dtVal);
            if (!isFinite(dt))
                continue;
            var year = dt.getFullYear();
            var month = dt.getMonth() + 1;
            var date = dt.getDate();
            var hours = dt.getHours();
            var mins = dt.getMinutes();
            dts[j].innerHTML = year + '-' + (month < 10 ? '0' : '') + month + '-' + (date < 10 ? '0' : '') + date + ' ' + Famark.getDisplayTime(hours, mins);
        }
    }
};

Famark.getElementsByClassName = function (cName, tName, node) {
    var els = [];
    var tmp, i;

    tName = tName || '*';
    node = node || document;

    if (node.getElementsByClassName) {
        tmp = node.getElementsByClassName(cName);
        for (i = 0; i < tmp.length; i++)
            els.push(tmp[i]);
    }
    else {
        var pattern = new RegExp('\\b' + cName + '\\b');
        tmp = node.getElementsByTagName(tName);
        for (i = 0; i < tmp.length; i++) {
            if (pattern.test(tmp[i].className))
                els.push(tmp[i]);
        }
    }

    return els;
};

Famark.clearSelection = function() {
    if (document.selection && document.selection.empty) {
        try {
            document.selection.empty();
        } catch (e) { }
    } else if (window.getSelection) {
        var sel = window.getSelection();
        sel.removeAllRanges();
    }
};

Famark.setCookie = function (key, value, minutes) {
    value = window.escape(value);
    if (minutes != null) {
        var now = new Date();
        now.setMinutes(now.getMinutes() + minutes);
        value += '; expires=' + now.toUTCString();
    }
    document.cookie = key + '=' + value;
};

Famark.getCookie = function (key) {
    if (document.cookie.length > 0) {
        var sPos = document.cookie.indexOf(key + '=');
        if (sPos != -1) {
            sPos = sPos + key.length + 1;
            var ePos = document.cookie.indexOf(';', sPos);
            if (ePos == -1)
                ePos = document.cookie.length;
            return window.unescape(document.cookie.substring(sPos, ePos));
        }
    }
    return null;
};