﻿/* Report Writer utility functions
 */

// initialize match extensions
jQuery.expr[':'].matchValue = function (a, i, m) {
    return (jQuery(a).attr('value').toUpperCase() == m[3].toUpperCase());
};
jQuery.expr[':'].matchTitle = function (a, i, m) {
    return (jQuery(a).attr('title').toUpperCase() == m[3].toUpperCase());
};

function initBlockUI() {
    if ($.blockUI)
        $(document).ajaxStart($.blockUI).ajaxStop($.unblockUI);
}

// Report List control
function rw_rlcInit(id) {
    var rc = $("#" + id);

    initBlockUI();

    rc.accordion({ autoHeight:false }).show();

    rc.ajaxError(function(event, xhr, ajaxOptions, thrownError) {
        alert(thrownError);
    });
    $("a.delete", rc).click(function() {
        var itemToRemove = $(this).parent();
        if (confirm(reportwriter.confirms.deletereport)) {
            $.post($(this).attr("href"), "", function(data, status, xhr) {
                itemToRemove.remove();
            });
        }
        return false;
    });
    $("a.view", rc).click(function() {
        var $this = $(this);
        var horizontalPadding = 120;
        var verticalPadding = 160;
        var targetWidth = $(window).width() - horizontalPadding;
        var targetHeight = $(window).height() - verticalPadding;

        $('<iframe id="externalSite" class="externalSite" src="' + this.href + '" frameborder="0" scrolling="no" width="' + targetWidth + '" height="' + targetHeight + '" />').dialog({
            title: ($this.html()) ? $this.html() : reportwriter.titles.reportwindow,
            autoOpen: true,
            width: targetWidth,
            height: targetHeight,
            modal: true,
            resizable: false,
            autoResize: true,
            overlay: {
                opacity: 0.5,
                background: "black"
            }
        }).width(targetWidth).height(targetHeight).css("padding", "0");

        return false;
    });
}

// Report Editor control
function rw_recInit(id, uniqueId) {
    var tc = $("#" + id);

    initBlockUI();

    $("input.cmd", tc).click(function () {
        var tabid = $(this).attr("tabid");
        var cmd = $(this).attr("cmd");

        if (isValidForm(tc, $(this).parents("div.ui-tabs-panel[id]"))) {
            var anchors = $("ul.ui-tabs-nav a", tc);
            var index = anchors.index(anchors.filter("[href$=" + tabid + "]"));

            // handle 'Next' or 'Save' command
            if (cmd == "next") {
                if ((index + 1) < anchors.length) {
                    tc.tabs("enable", (index + 1));
                    tc.tabs("select", (index + 1));
                }
            } else if (cmd == "save") {
                aspnetAjaxPost(uniqueId, cmd,
                    function(data) {
                        eval(data);
                    }
                );
            }
        } else {
            var err = $("label.error:first", tc);
            var errtabid = err.parents("div.ui-tabs-panel[id]").attr("id");

            if (tabid != errtabid)
                tc.tabs("select", errtabid);
        }
    });

    // initialize tabs UI and behaviour
    initSourceTables(tc);

    $("ul.dest", tc).sortable({
        receive: function() {
            $(".ui-icon-plus", this).removeClass("ui-icon-plus").addClass("ui-icon-minus").attr("title", reportwriter.tooltips.remove).unbind("click").click(function() {
                removeSelectedColumn(tc, $(this).parent());
            });
        },
        update: function() {
            serializeSelectedColumns(tc);
        }
    });
    $("ul.sort", tc).sortable({
        update: function() {
            serializeSortingAggregates(tc);
        }
    });
    $("ul.expr", tc).sortable({
        update: function() {
            serializeFilterExpressions(tc);
        }
    });
    initSelectedColumns(tc);
    initSortingAggregates(tc);
    initFilterExpressions(tc);

    // handle change of fields
    $("select[name$=_DataSource]", tc).change(function() {
        if ($(this).val().length) {
            aspnetAjaxPost(uniqueId, "dschange",
                function(data) {
                    var od = $(data);
                    var catList = $("select[name$=_Category]", od);
                    var availCols = $("div.tables", od);

                    if (catList.length)
                        $("select[name$=_Category]", tc).replaceWith(catList);
                    if (availCols.length) {
                        $("div.tables", tc).replaceWith(availCols);
                        initSourceTables(tc);
                    }
                },
                function(e) {
                    $(this).val("");
                    alert(e);
                }
            );
        } else {
            $("select[name$=_Category] option[value!='']", tc).remove();
            $("div.tables > *", tc).remove();
        }
        $("input[name$=_SelectedColumns]", tc).val("");
        $("input[name$=_SortingAggregates]", tc).val("");
        $("input[name$=_FilterExpressions]", tc).val("");

        initSelectedColumns(tc);
        initSortingAggregates(tc);
        initFilterExpressions(tc);
    });
    $("select[name$=_ReportType]", tc).change(function() {
        $("span.matrix select", tc).val("");
        showHideMatrix(tc);
    });

    tc.tabs().show();
}

function aspnetPost(target, arg) {
    if (__doPostBack)
        __doPostBack(target, arg);
}

function aspnetAjaxPost(target, arg, cbSuccess, cbError) {
    var form = $("form[name=aspnetForm]");
    var action = form.attr("action");

    $("input[name=__EVENTTARGET]").val(target);
    $("input[name=__EVENTARGUMENT]").val(arg);
    aspnetAjaxPostData(action, form.serialize(), cbSuccess, cbError);
}

function aspnetAjaxPostData(action, formData, cbSuccess, cbError) {
    $.ajax({
        type: "POST",
        url: action,
        data: formData,
        cache: false,
        success: function(data) {
            cbSuccess && cbSuccess(data);
        },
        error: function(xhr, e) {
            if (cbError)
                cbError(e);
            else
                alert(e);
        },
        complete: function(xhr, status) {
            $("input[name=__EVENTTARGET]").val("");
            $("input[name=__EVENTARGUMENT]").val("");
        }
    });
}

function isValidForm(tc, curtab) {
    var valid = true;

    $("label.error", tc).remove();
    $("div.cmds span.label", tc).show();
    
    valid = $("form").valid();
    if (valid) {
        var tab2 = $("div.ui-tabs-panel[id$=Tab2]", tc);

        if (curtab.attr("id") >= tab2.attr("id"))
            valid = validTest(($("input[name$=_SelectedColumns]", tab2).val() == ""), tab2, reportwriter.validations.need1column);
    }
    if (valid) {
        var reportType = $("select[name$=_ReportType]", tc).val();

        if (reportType == "2") {
            var tab3 = $("div.ui-tabs-panel[id$=Tab3]", tc);

            if (curtab.attr("id") >= tab3.attr("id")) {
                valid = validTest(($("span.matrix select[value=COLUMN]", tab3).length == 0), tab3, reportwriter.validations.need1matrixrow);
                if (valid)
                    valid = validTest(($("span.matrix select[value=ROW]", tab3).length == 0), tab3, reportwriter.validations.need1matrixcolumn);
                if (valid)
                    valid = validTest(($("span.matrix select[value='']", tab3).length == 0), tab3, reportwriter.validations.need1matrixsummary);
            }
        }
    }
    if (valid) {
        var tab4 = $("div.ui-tabs-panel[id$=Tab4]", tc);
        if (!tab4.attr("id"))   // check for view filters
            tab4 = $("#filtersId");
        if (curtab.attr("id") >= tab4.attr("id")) {
            valid = validTest(($("ul.expr span.column select[value='']", tab4).length > 0), tab4, reportwriter.validations.needfiltercolumn);
            if (valid)
                valid = validTest(($("ul.expr span.oper select[value='']", tab4).length > 0), tab4, reportwriter.validations.needfilteroperator);
        }
    }
    return valid;
}

function validTest(expr, tab, msg) {
    var valid = true;
    if (expr) {
        $("div.cmds", tab).prepend("<label class=\"error\">" + msg + "</label>");
        $("div.cmds span.label", tab).hide();
        valid = false;
    }
    return valid;
}

function validateForm(tc) {
    if ($.valid)
        isValidForm(tc, $("div.ui-tabs-panel[id]:visible", tc));
}

function initSourceTables(tc) {
    $("div.tables", tc).accordion({
        autoHeight: false,
        collapsible: true
    });
    $("ul.src", tc).sortable({ connectWith: "ul.dest" });
    $("ul.src li", tc).append("<span class=\"ui-icon ui-icon-plus\" title=\"" + reportwriter.tooltips.add + "\"></span>");
    $("ul.src li span.ui-icon", tc).click(function() {
        var col = $(this).prev("span.column");
        addSelectedColumn(tc, col.attr("title"), col.attr("column"), col.attr("hint"), col.attr("display"), "True");
    });
    $("ul.src li input.visible", tc).click(function() {
        serializeSelectedColumns(tc, true);
    });
}

function addSelectedColumn(tc, table, column, hint, display, visible, dontSerialize) {
    var item = $("<li><input type=\"checkbox\" class=\"visible\" value=\"True\" title=\"" + reportwriter.tooltips.visible + "\" " + (visible == "True" ? "checked=checked" : "") + " /><span class=\"column\" title=\"" + table + "\" column=\"" + column + "\" hint=\"" + hint
        + "\" display=\"" + display + "\">" + display + "</span><span class=\"ui-icon ui-icon-minus\" title=\"" + reportwriter.tooltips.remove + "\"></span></li>");

    $("ul.dest", tc).append(item);
    $("span.ui-icon", item).click(function() {
        removeSelectedColumn(tc, $(this).parent());
    });
    $("input.visible", item).click(function() {
        serializeSelectedColumns(tc, true);
    });
    $("div.tables h3 a[title=" + table + "][hint=" + hint + "]", tc).parent().next().find("li span.column[column=" + column + "][hint=" + hint + "]", tc).parent().remove();

    if (dontSerialize == undefined || !dontSerialize)
        serializeSelectedColumns(tc);
}

function removeSelectedColumn(tc, item) {
    var newItem = $(item).clone(false);
    var col = $("span.column", newItem);

    $(item).remove();
    $("a[title=" + col.attr("title") + "][hint=" + col.attr("hint") + "]", tc).parent().next().append(newItem);
    $(".ui-icon-minus", newItem).removeClass("ui-icon-minus").addClass("ui-icon-plus").attr("title", reportwriter.tooltips.add).click(function () {
        var col = $(this).prev("span.column");
        addSelectedColumn(tc, col.attr("title"), col.attr("column"), col.attr("hint"), col.attr("display"), "True");
        $(this).parent().remove();
    });
    serializeSelectedColumns(tc);
}

function serializeSelectedColumns(tc, selColsOnly) {
    var hidSelCols = $("input[name$=_SelectedColumns]", tc);
    var selCols = "";

    $("ul.dest li span.column", tc).each(function(index, domEl) {
        var el = $(domEl);
        if (selCols != "")
            selCols += "|";
        selCols += (el.attr("title") + ":" + el.attr("column") + ":" + el.attr("hint")
            + ":" + (el.parent().find("input.visible:checked").val() == "True" ? "True" : "False"));
    });
    hidSelCols.val(selCols);

    if (selColsOnly == undefined || !selColsOnly) {
        initSortingAggregates(tc);
        initFilterExpressions(tc);
    }
}

function initSelectedColumns(tc) {
    var selCols = $("input[name$=_SelectedColumns]", tc).val().split("|");

    $("ul.dest li", tc).remove();
    for (var i = 0; i < selCols.length; i++) {
        var pair = selCols[i].split(":");
        if (pair.length >= 2 && pair[0].length && pair[1].length)
            addSelectedColumn(tc, pair[0], pair[1], (pair.length >= 3 ? pair[2] : ""), (pair.length >= 4 && pair[3] ? pair[3] : pair[1]), (pair.length >= 5 ? pair[4] : "True"), true);
    }
}

function initSortingAggregates(tc) {
    var selCols = $("input[name$=_SelectedColumns]", tc).val().split("|");
    var sortAggs = $("input[name$=_SortingAggregates]", tc).val().split("|");
    var newSortAggs = new Array();

    for (var j = 0; j < sortAggs.length; j++) {
        var params = sortAggs[j].split(":");
        if (params.length >= 2) {
            for (var i = 0; i < selCols.length; i++) {
                var pair = selCols[i].split(":");
                if (pair.length >= 2 && pair[0].match(new RegExp(params[0], "i")) && pair[1].match(new RegExp(params[1], "i"))
                    && (pair.length == 2 || pair[2].match(new RegExp(params[2], "i")))) {
                    newSortAggs[newSortAggs.length] = sortAggs[j];
                    break;
                }
            }
        }
    }
    for (var i = 0; i < selCols.length; i++) {
        var pair = selCols[i].split(":");
        if (pair.length >= 2 && pair[0].length && pair[1].length) {
            var found = false;
            for (var j = 0; j < newSortAggs.length; j++) {
                var params = newSortAggs[j].split(":");
                if (params.length >= 2 && pair[0].match(new RegExp(params[0], "i")) && pair[1].match(new RegExp(params[1], "i"))
                    && (pair.length == 2 || pair[2].match(new RegExp(params[2], "i")))) {
                    found = true;
                    break;
                }
            }
            if (!found)
                newSortAggs[newSortAggs.length] = selCols[i];
        }
    }

    $("ul.sort li", tc).remove();
    for (var j = 0; j < newSortAggs.length; j++) {
        var params = newSortAggs[j].split(":");
        if (params.length >= 2) {
            var hint = (params.length >= 3 ? params[2] : "");
            var sort = (params.length >= 4 ? params[3] : "");
            var agg = (params.length >= 5 ? params[4] : "");
            var matrix = (params.length >= 6 ? params[5] : "");
            addSortingColumn(tc, params[0], params[1], hint, sort, agg, matrix);
        }
    }
    serializeSortingAggregates(tc);
    showHideMatrix(tc);
    validateForm(tc);
}

function addSortingColumn(tc, table, column, hint, sort, agg, matrix) {
    var id = tc.attr("id");
    var sortEl = "<span class=\"sort\"><label>Sorting:</label> " + generateSortList(id + "_sort", sort) + "</span>";
    var aggEl = "<span class=\"agg\"><label>Aggregate:</label> " + generateAggregateList(id + "_agg", agg) + "</span>";
    var matrixEl = "<span class=\"matrix\"><label>Matrix:</label> " + generateMatrixList(id + "_matrix", matrix) + "</span>";
    var display = $("ul.dest span.column[title=" + table + "][column=" + column + "]", tc).html();
    var item = $("<li><span class=\"column\" title=\"" + table + "\" column=\"" + column + "\" hint=\"" + hint + "\">" + display + "</span>" + matrixEl + sortEl + aggEl + "</li>");

    $("select", item).change(function() {
        serializeSortingAggregates(tc);
    });
    $("ul.sort", tc).append(item);
}

function generateSortList(id, selected) {
    var sb = "";

    sb += "<select name=\"" + id + "\">";
    sb += "<option value=\"\">" + reportwriter.options.emptytext + "</option>";
    sb += "<option value=\"ASC\" " + (selected.match(new RegExp("ASC"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.sortascending + "</option>";
    sb += "<option value=\"DESC\" " + (selected.match(new RegExp("DESC"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.sortdescending + "</option>";
    sb += "</select>";
    
    return sb;
}

function generateAggregateList(id, selected) {
    var sb = "";

    sb += "<select name=\"" + id + "\">";
    sb += "<option value=\"\">" + reportwriter.options.emptytext + "</option>";
    sb += "<option value=\"AVG\" " + (selected.match(new RegExp("AVG"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.aggregateaverage + "</option>";
    sb += "<option value=\"COUNT\" " + (selected.match(new RegExp("COUNT"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.aggregatecount + "</option>";
    sb += "<option value=\"MIN\" " + (selected.match(new RegExp("MIN"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.aggregateminimum + "</option>";
    sb += "<option value=\"MAX\" " + (selected.match(new RegExp("MAX"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.aggregatemaximum + "</option>";
    sb += "<option value=\"SUM\" " + (selected.match(new RegExp("SUM"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.aggregatesum + "</option>";
    sb += "</select>";

    return sb;
}

function generateMatrixList(id, selected) {
    var sb = "";

    sb += "<select name=\"" + id + "\">";
    sb += "<option value=\"COLUMN\" " + (selected.match(new RegExp("COLUMN"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.matrixcolumn + "</option>";
    sb += "<option value=\"ROW\" " + (selected.match(new RegExp("ROW"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.matrixrow + "</option>";
    sb += "<option value=\"\" " + (selected == "" ? "selected=selected" : "") + ">" + reportwriter.options.matrixsummary + "</option>";
    sb += "</select>";

    return sb;
}

function serializeSortingAggregates(tc) {
    var hidSortAggs = $("input[name$=_SortingAggregates]", tc);
    var sortAggs = "";

    $("ul.sort li span.column", tc).each(function(index, domEl) {
        var el = $(domEl);
        if (sortAggs != "")
            sortAggs += "|";
        sortAggs += (el.attr("title") + ":" + el.attr("column") + ":" + el.attr("hint") + ":" + el.parent().find("span.sort select").val()
            + ":" + el.parent().find("span.agg select").val() + ":" + el.parent().find("span.matrix select").val());
    });
    hidSortAggs.val(sortAggs);
}

function showHideMatrix(tc) {
    var reportType = $("select[name$=_ReportType]", tc).val();
    var matEl = $("span.matrix", tc);

    if (reportType == "2")
        matEl.show();
    else
        matEl.hide();
}

function initFilterExpressions(tc) {
    var filtExprs = $("input[name$=_FilterExpressions]", tc).val().split("|");

    $("ul.newexpr li", tc).remove();
    addFilterExpression(tc, "", "", "", "", "", "", true);
    
    $("ul.expr li", tc).remove();
    for (var j = 0; j < filtExprs.length; j++) {
        var params = filtExprs[j].split(":");
        if (params.length >= 2) {
            var hint = (params.length >= 3 ? params[2] : "");
            var oper = (params.length >= 4 ? params[3] : "");
            var value = (params.length >= 5 ? params[4] : "");
            var condition = (params.length >= 6 ? params[5] : "");
            addFilterExpression(tc, params[0], params[1], hint, oper, value, condition, false);
        }
    }
    
    serializeFilterExpressions(tc);
    validateForm(tc);
}

function escapeHTML(str) {
    return $("<div/>").text(str).html()
}

function addFilterExpression(tc, table, column, hint, oper, value, condition, forAdding) {
    var id = tc.attr("id");
    var colsEl = "<span class=\"column\"><label>Column:</label> " + generateColumnList(tc, id + "_column", (table + "#" + column + "#" + hint)) + "</span>";
    var operEl = "<span class=\"oper\"> " + generateOperatorList(id + "_oper", oper) + " </span>";
    var valueEl = "<span class=\"value\"><input type=\"\" value=\"" + escapeHTML(value) + "\" /></span>";
    var condEl = "<span class=\"condition\"> " + generateConditionList(id + "_condition", condition) + " </span>";
    var addDelEl = "<span class=\"cmds\"><input type=\"button\" class=\"" + (forAdding ? "add" : "del") + "\" value=\"" + (forAdding ? reportwriter.buttons.filteradd : reportwriter.buttons.filterdelete) + "\" /></span>"
    var item = $("<li>" + colsEl + operEl + valueEl + condEl + addDelEl + "</li>");

    if (forAdding) {
        $("input.add", item).click(function() {
            var parent = $(this).parents("li");
            var column = $("span.column select", parent).val().split("#");
            addFilterExpression(tc, column[0], column[1], column[2], $("span.oper select", parent).val(), $("span.value input", parent).val(),
                $("span.condition select", parent).val(), false);
            $("select, input[type=text]", parent).val("");
            serializeFilterExpressions(tc);
        });
        $("span.condition", item).hide();
    } else {
        $("select, input[type=text]", item).change(function() {
            serializeFilterExpressions(tc);
        });
        $("input.del", item).click(function() {
            $(this).parents("li").remove();
            serializeFilterExpressions(tc);
        });
    }
    $((forAdding ? "ul.newexpr" : "ul.expr"), tc).append(item);
}

function generateColumnList(tc, id, selected) {
    var selCols = $("input[name$=_SelectedColumns]", tc).val().split("|");
    var sb = "";

    sb += "<select name=\"" + id + "\">";
    sb += "<option value=\"\">" + reportwriter.options.emptytext + "</option>";
    for (var i = 0; i < selCols.length; i++) {
        var pair = selCols[i].split(":");
        if (pair.length >= 2 && pair[0].length && pair[1].length) {
            var colVal = pair[0] + "#" + pair[1] + "#" + (pair.length >= 3 ? pair[2] : "");
            var display = $("ul.dest span.column[title=" + pair[0] + "][column=" + pair[1] + "]", tc).html();
            sb += "<option value=\"" + colVal + "\" title=\"" + pair[0] + "\" " + (selected.match(new RegExp(colVal), "i") ? "selected=selected" : "") + ">" + display + "</option>";
        }
    }
    sb += "</select>";

    return sb;
}

function generateOperatorList(id, selected) {
    var sb = "";

    sb += "<select name=\"" + id + "\">";
    sb += "<option value=\"\">" + reportwriter.options.operatorempty + "</option>";
    sb += "<option value=\"EQ\" " + (selected.match(new RegExp("EQ"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorequals + "</option>";
    sb += "<option value=\"NEQ\" " + (selected.match(new RegExp("NEQ"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatornotequals + "</option>";
    sb += "<option value=\"GT\" " + (selected.match(new RegExp("GT"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorgreaterthan + "</option>";
    sb += "<option value=\"LT\" " + (selected.match(new RegExp("LT"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorlessthan + "</option>";
    sb += "<option value=\"GTE\" " + (selected.match(new RegExp("GTE"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorgreaterequals + "</option>";
    sb += "<option value=\"LTE\" " + (selected.match(new RegExp("LTE"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorlessequals + "</option>";
    sb += "<option value=\"NULL\" " + (selected.match(new RegExp("NULL"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorisnull + "</option>";
    sb += "<option value=\"NNULL\" " + (selected.match(new RegExp("NNULL"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatornotnull + "</option>";
    sb += "<option value=\"WITH\" " + (selected.match(new RegExp("WITH"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorcontains + "</option>";
    sb += "<option value=\"SWITH\" " + (selected.match(new RegExp("SWITH"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorstartswith + "</option>";
    sb += "<option value=\"EWITH\" " + (selected.match(new RegExp("EWITH"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorendswith + "</option>";
    sb += "<option value=\"TODAY\" " + (selected.match(new RegExp("TODAY"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatortoday + "</option>";
    sb += "</select>";

    return sb;
}

function generateConditionList(id, selected) {
    var sb = "";

    sb += "<select name=\"" + id + "\">";
    sb += "<option value=\"AND\" " + (selected.match(new RegExp("AND"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatorand + "</option>";
    sb += "<option value=\"OR\" " + (selected.match(new RegExp("OR"), "i") ? "selected=selected" : "") + ">" + reportwriter.options.operatoror + "</option>";
    sb += "</select>";

    return sb;
}

function serializeFilterExpressions(tc) {
    var hidFiltExprs = $("input[name$=_FilterExpressions]", tc);
    var filtExprs = "";

    $("ul.expr li", tc).each(function(index, domEl) {
        var el = $(domEl);
        var column = el.find("span.column select").val().split("#");
        if (filtExprs != "")
            filtExprs += "|";
        filtExprs += (column[0] + ":" + column[1] + ":" + column[2] + ":" + el.find("span.oper select").val()
            + ":" + el.find("span.value input").val() + ":" + el.find("span.condition select").val());
    });
    hidFiltExprs.val(filtExprs);

    $("ul.expr span.condition", tc).show();
    $("ul.expr span.condition:last", tc).hide();
}

// View Report control
function rw_viewInit(id) {
    var tc = $("form.tabs");

    $("input.cmd", tc).click(function() {
        if (isValidForm(tc, $(this).parents("div.ui-tabs-panel[id]"))) {
            var cmd = $(this).attr("cmd");

            aspnetPost(id, cmd);
        }
    });
    $("ul.expr", tc).sortable({
        update: function() {
            serializeFilterExpressions(tc);
        }
    });

    initSelectedColumns(tc);
    initFilterExpressions(tc);
    
    tc.tabs().show();
}


// Grid control
function rw_gcInit(id, colModel, caption, loadUrl, editUrl, canReorder, loadOnce, funcs, initWidth, initHeight) {
    var gridId = "#" + id + "Grid";
    var pagerId = gridId + "Pager";
    var editfunc = funcs.addeditfunc;
    var deletefunc = funcs.deletefunc;
    var enablefunc = funcs.enablefunc;
    var selectfunc = funcs.selectfunc;

    // recompute target width based on contained items
    var innerWrap = $(gridId).parents("#wrap-inner");
    var parentWrap = (innerWrap.length > 0 ? innerWrap : $(gridId).parents("#wrap"));
    var adminNav = parentWrap.find("div.admin-nav");
    var targetWidth = (initWidth || (parentWrap.width() || 630));
    var targetHeight = (initHeight || 240);

    if (adminNav.length > 0)
        targetWidth -= (adminNav.width() + 30);

    var loadFunc = function (postdata) {
        loadGrid(id, postdata);
        if (loadOnce)
            $(gridId).setGridParam({ datatype: "local" });
    };
    $(gridId).data("_loadFunc", loadFunc);

    $(gridId).jqGrid({
        datatype: loadFunc,
        jsonReader: {
            root: "rows",
            total: "pages",
            page: "current",
            records: "records",
            id: "0",
            repeatitems: false
        },
        colModel: colModel,
        rowNum: (!loadOnce ? 20 : 100),
        rowList: (!loadOnce ? [10, 20, 50] : []),
        pgbuttons: !loadOnce,
        pginput: !loadOnce,
        viewrecords: true,
        url: loadUrl,
        editurl: editUrl,
        pager: (pagerId),
        caption: caption,
        width: targetWidth,
        height: targetHeight,
        gridComplete: function () {
            var grid = $(gridId);
            var ids = grid.jqGrid('getDataIDs');
            for (var i = 0; i < ids.length; i++) {
                var cl = ids[i];
                var editEnabled = ((enablefunc && enablefunc.length) ? eval(enablefunc + "(" + cl + ", 'edit')") : true);
                var deleteEnabled = ((enablefunc && enablefunc.length) ? eval(enablefunc + "(" + cl + ", 'del')") : true);

                be = "<a href=\"#\" onclick=\"" +
                    (editEnabled ? ((editfunc && editfunc.length) ? ("eval('" + editfunc + "(" + cl + ")');") : ("$('" + gridId + "').jqGrid('editGridRow', '" + cl + "', { errorTextFormat: errorTextFormat });")) : "")
                    + " return false;\" " + (!editEnabled ? "disabled=\"disabled\"" : "") + ">" + reportwriter.buttons.gridedit + "</a>";
                se = "<a href=\"#\" onclick=\"" +
                    (deleteEnabled ? ((deletefunc && deletefunc.length) ? ("eval('" + deletefunc + "(" + cl + ")');") : ("$('" + gridId + "').jqGrid('delGridRow', '" + cl + "', { errorTextFormat: errorTextFormat });")) : "")
                    + " return false;\" " + (!deleteEnabled ? "disabled=\"disabled\"" : "") + ">" + reportwriter.buttons.griddelete + "</a>";
                grid.jqGrid('setRowData', ids[i], { Act: be + "&nbsp;" + se });
            }
        },
        loadonce: loadOnce,
        rownumbers: loadOnce,
        rownumWidth: 20,
        shrinkToFit: false,
        onSelectRow: function (id) {
            if (selectfunc && selectfunc.length)
                eval(selectfunc + "('" + (id || "") + "')");
        }
    });
    $(gridId).navGrid(pagerId, {
        add: (editUrl || editfunc),
        del: false,
        edit: false,
        refresh: false,
        search: false,
        addtext: reportwriter.buttons.gridnew,
        addtitle: reportwriter.titles.gridaddwindow.replace("{0}", caption),
        addfunc: function () {
            if (editfunc && editfunc.length)
                eval(editfunc + "()");
            else
                $(gridId).jqGrid("editGridRow", "new", { errorTextFormat: errorTextFormat });
        }
    });

    if (canReorder)
        $(gridId).jqGrid("sortableRows");

    $("#" + id).show();
}

function reloadGrid(id) {
    var gridId = "#" + id + "Grid";
    var grid = $(gridId);
    var loadOnce = grid.getGridParam("loadonce");

    if (loadOnce) {
        var loadFunc = grid.data("_loadFunc");
        if (loadFunc)
            grid.setGridParam({ datatype: loadFunc });
    }
    grid.trigger("reloadGrid");
}

function loadGrid(id, postdata) {
    var gridId = "#" + id + "Grid";
    var loadingId = "#load_" + id + "Grid";

    postdata.categoryId = $("#" + id + " select.category").val() || "";
    postdata.keyword = $("#" + id + " input.keyword").val() || "";
    $(loadingId).show();
    $.ajax({
        url: $(gridId).getGridParam("url"),
        data: JSON.stringify(postdata),
        dataType: "json",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        success: function (data, textStatus, XMLHttpRequest) {
            var loadOnce = $(gridId).getGridParam("loadonce");
            var editurl = $(gridId).getGridParam("editurl");

            // check for columns show/hide, and edit options
            if (data.d && data.d.extra) {
                var colModel = $(gridId).getGridParam("colModel");
                var lvInfo = [];
                var toHide = [];
                var toShow = [];
                var colOrders = [];

                for (var j = 0; j < data.d.extra.length; j++) {
                    for (var i = 0; i < colModel.length; i++) {
                        if (colModel[i].name.toUpperCase() == data.d.extra[j].Id.toUpperCase()) {
                            lvInfo.push(data.d.extra[j])
                            colOrders.push(i);
                            break;
                        }
                    }
                }
                for (var i = 0; i < colModel.length; i++) {
                    var isVisible = false;
                    var label = null;
                    var values = null;
                    var found = false;

                    for (var j = 0; j < lvInfo.length; j++) {
                        if (colModel[i].name.toUpperCase() == lvInfo[j].Id.toUpperCase()) {
                            label = lvInfo[j].Label;
                            isVisible = lvInfo[j].IsVisible;
                            if (colModel[i].name == "Act" && (!editurl))
                                isVisible = false;
                            values = lvInfo[j].ListValues;
                            found = true;
                            break;
                        }
                    }
                    if (isVisible)
                        toShow.push(colModel[i].name);
                    else
                        toHide.push(colModel[i].name);

                    if (!found)
                        colOrders.push(i);

                    if (label)
                        $(gridId).setLabel(i, label);
                    if (values && values.length) {
                        if (!colModel[i].origFormatter)
                            colModel[i].origFormatter = colModel[i].formatter;
                        $(gridId).setColProp(colModel[i].name, { align: "left", formatter: "select", editoptions: { value: values} });
                    } else if (colModel[i].origFormatter) {
                        $(gridId).setColProp(colModel[i].name, { align: "right", formatter: colModel[i].origFormatter });
                    }
                    if (colModel[i].origWidth)
                        colModel[i].width = colModel[i].origWidth;
                }
                $(gridId).remapColumns(colOrders, true, false);
                $(gridId).hideCol(toHide);
                $(gridId).showCol(toShow);

                colModel = $(gridId).getGridParam("colModel");
            }
            if (loadOnce) {
                var rows = data.d.rows;
                $(gridId).clearGridData();
                if (rows) {
                    for (var i = 0; i < rows.length; i++)
                        $(gridId).addRowData((i + 1), rows[i]);
                }
            } else {
                $(gridId)[0].addJSONData(data.d);
            }
            // fix for IE7 table empty cells display
            if (jQuery.browser.msie && parseInt(jQuery.browser.version) < 8)
                $("tr.jqgrow td:empty", gridId).html("&nbsp;");

            $(gridId).setGridWidth($(gridId).getGridParam("width"), true);
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert(errorTextFormat(XMLHttpRequest));
        },
        complete: function (jsondata, stat) {
            $(loadingId).hide();
        }
    });
}

function errorTextFormat(data) {
    var patt = /<title>(.*?)<\/title>/im;
    var statTitle = patt.exec(data.responseText);
    return reportwriter.messages.errorstatus.replace("{0}", (statTitle && statTitle.length > 1 ? statTitle[1] : "Unknown error."));
}

/*
function ndateFormatter(cellval, opts, rwdat, _act) {
    if (cellval) {
        var time = cellval.replace(/\/Date\(([0-9]*)\)\//, '$1');
        var date = new Date();
        date.setTime(time);
        if (!isNaN(date.getTime()))
            return $.datepicker.formatDate("yy-mm-dd", date);
    }
    return "";
}*/

function urlFormatter(cellval, opts, rwdat, _act) {
    if (!isNaN(cellval)) {
        var html = (opts.colModel.label ? formatUrlLabel(cellval, opts.colModel.label) : "");
        var href = opts.colModel.formatoptions.baseLinkUrl + "?" + opts.colModel.formatoptions.idName + "=" + rwdat[opts.colModel.formatoptions.idValue] + opts.colModel.formatoptions.addParam;
        return "<a href=\"" + href + "\">" + html + "</a>";
    } else {
        var val = rwdat[opts.colModel.formatoptions.idValue];
        var href = opts.colModel.formatoptions.baseLinkUrl + "?" + opts.colModel.formatoptions.idName + "=" + val + opts.colModel.formatoptions.addParam;
        return "<a href=\"" + href + "\">" + val + "</a>";
    }
    return ""
}

function formatUrlLabel(val, label) {
    var c = parseInt(val);

    if (c == 1) {
        if (/ies$/i.test(label))
            label = label.substr(0, label.length - 3) + "y";
        else if (/s$/i.test(label))
            label = label.substr(0, label.length - 1);
    } else if (c > 1) {
        if (/y$/i.test(label))
            label = label.substr(0, label.length - 1) + "ies";
        else if (!/s$/i.test(label))
            label += "s";
    }
    return (parseInt(val) > 0 ? (val + " ") : "") + label;
}

function rw_gcSave(id) {
    var gridId = "#" + id + "Grid";
    var editUrl = $(gridId).getGridParam("editurl");
    var colModel = $(gridId).getGridParam("colModel");
    var rows = $(gridId).getRowData();
    var postdata = [];

    for (var i = 0; i < rows.length; i++) {
        var row = rows[i];
        var rowdata = [];
        for (var j = 0; j < colModel.length; j++) {
            var col = colModel[j];
            if (col.posted) {
                var val = row[col.name] || "";
                if (!col.editable && val == "undefined")
                    val = "";
                rowdata.push(col.name + "=" + encodeURIComponent(val));
            }
        }
        postdata.push("_row" + i + "=" + encodeURIComponent(rowdata.join("&")));
    }
    postdata.push("oper=save");
    postdata.push("categoryId=" + $("#" + id + " select.category").val() || "");

    // save attributes now using ordinary FORM post
    if ($.blockUI)
        $.blockUI();
    $.ajax({
        url: editUrl,
        data: postdata.join("&"),
        type: "POST",
        success: function (data, textStatus, XMLHttpRequest) {
            loadGrid(id, {});
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert(errorTextFormat(XMLHttpRequest));
        },
        complete: function (jsondata, stat) {
            if ($.unblockUI)
                $.unblockUI();
        }
    });
}


// Site columns helper
function initSiteColumns(gridId, dlgId) {
    var grid = $("#" + gridId);
    var pagerId = gridId + "Pager";

    grid.navButtonAdd("#" + pagerId, {
        caption: reportwriter.titles.sitecolumns,
        buttonicon: "ui-icon-newwin",
        onClickButton: function () {
            var dlg = $("#" + dlgId);

            dlg.dialog({
                modal: true,
                width: 490,
                height: 320,
                open: function () {
                    var msel = $(".multiselect", dlg);
                    
                    $.extend($.ui.multiselect.locale, {
                        addAll: reportwriter.messages.sitecolumnsaddall,
                        removeAll: reportwriter.messages.sitecolumnsremoveall,
                        itemsCount: reportwriter.messages.sitecolumnsitemscount
                    });
                    msel.multiselect();
                    refreshSiteColumns(grid, dlg);

                    $("body").css("overflow", "hidden");
                },
                close: function () {
                    $("body").css("overflow", "auto");
                },
                buttons: {
                    "Select": function () {
                        refreshSiteColumnGrid(grid, dlg);
                        dlg.dialog("close");
                    },
                    "Cancel": function () {
                        dlg.dialog("close");
                    }
                }
            });

        },
        position: "last"
    });
}

function refreshSiteColumns(grid, parent) {
    var rows = grid.getRowData();
    var msel = $(".multiselect", parent);

    $(".remove-all", parent).click();

    for (var i = 0; i < rows.length; i++) {
        var row = rows[i];
        var id = row["Id"];
        var name = $("option:matchValue(" + id + ")", msel).html();

        if (name)
            $("li:matchTitle(" + name + ") a.action", parent).click();
    }
}

function attributeInfo() {
    this.Id = "";
    this.Label = "";
    this.DataType = "";
    this.DataLength = 0;
    this.Description = "";
    this.IsRequired = false;
    this.IsListViewDisplay = false;
    this.SectionName = "";
    this.Values = "";
    this.IsSiteColumn = false;
    this.IsInherited = false;
}

function refreshSiteColumnGrid(grid, parent) {
    var rows = grid.getRowData();
    var msel = $(".multiselect", parent);
    var selCols = msel.val();

    if (selCols) {
        var rows = grid.getRowData();
        var numRows = rows.length;

        for (var i = 0; i < selCols.length; i++) {
            var id = selCols[i];
            var exists = false;

            for (var j = 0; j < rows.length; j++) {
                if (id.toUpperCase() == rows[j]["Id"].toUpperCase()) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                var selOpt = $("option:matchValue(" + id + ")", msel);
                var data = new attributeInfo();

                data.Id = id;
                data.Label = selOpt.html();
                data.DataType = selOpt.attr("datatype");
                data.DataLength = parseInt(selOpt.attr("datalength"));
                data.Description = selOpt.attr("desc");
                data.IsRequired = (selOpt.attr("required") == "true");
                data.IsListViewDisplay = (selOpt.attr("listview") == "true");
                data.Values = selOpt.attr("attrvalues");
                data.SectionName = selOpt.attr("section");
                data.IsSiteColumn = true;

                grid.addRowData(numRows++, data);
            }
        }
    }
}


/* helper utils */
function showReadMore(obj) {
    var $this = $(obj);

    $this.next(".readmore").show();
    $this.hide();

    return false;
}


/* tabs */
$(document).ready(function () {

    //    //When page loads...
    //    $(".tab_content").hide(); //Hide all content
    //    $(".tab_content:first").show(); //Show first tab content

    //    //When page loads...
    //    $(".tab_content_main").hide(); //Hide all content
    //    $(".tab_content_main:first").show(); //Show first tab content

    //    $("ul.tabs li:first-child").addClass("active").show(); //Activate first tab

    //On Click Event
    $("ul.tabs li").click(function () {
        var inactiveTab = $(this).siblings(".active").find("a").attr("href");
        $(inactiveTab).hide();

        $(this).siblings().removeClass("active"); //Remove any "active" class
        $(this).addClass("active"); //Add "active" class to selected tab

        var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
        $(activeTab).fadeIn(); //Fade in the active ID content
        return (activeTab.length > 0 && activeTab[0] != "#");
    });
});
