﻿// Query
var query = new MWQuery();



// Query object
function MWQuery() {
    this.items = new Array();
    this.fieldsToClear = new Array();
    this.itemsToDelete = new Array();
    this.additionalQSParams = {};
    this.pageNumber = "";
    this.pageSize = "";
    this.maxPageNumber = "";
    this.resultViewName = "";
    this.sortOrder = "";
    this.maximumNavigatorCriteriaSize = 1500;
    this.resultPage = document.location.pathname; // default to showing search results on "current page"

    // Store company id parameter on query object
    // (was earlier using Prototype's toQueryParams but that failed on strings such as '/Resultat.aspx?soegeord=s%E6lger')
    var myself = this;
    location.search.replace('?', '').split('&').inject({}, function (hash, pair) {
        if (pair.substring(0, 7) == 'compid=') {
            if ((pair = pair.split('='))[0]) {
                var key = decodeURIComponent(pair.shift()),
                    value = pair.length > 1 ? pair.join('=') : pair[0];
                myself.compid = value;
            }
        }
    });

    this.AddQsParameter = function (name, qsValue) {
        this.additionalQSParams[name] = qsValue;
    }

    this.SetResultPage = function (resultPage) {
        this.resultPage = resultPage;
    }

    this.SetPageInformation = function (pageNumber, pageSize, maxPageNumber) {
        this.pageNumber = pageNumber;
        this.pageSize = pageSize;
        this.maxPageNumber = maxPageNumber;
    }

    this.SetPageNumber = function (number) {
        if ((number == "") || ((parseFloat(number) >= 1) && (parseFloat(number) <= this.maxPageNumber) && (parseFloat(number) != this.pageNumber))) {
            this.pageNumber = number;
            return true;
        }
        return false;
    }

    this.SetPageSize = function (number) {
        if ((number == "") || (parseFloat(number) >= 1)) {
            this.pageSize = number;
        }
    }

    this.SetResultView = function (name) {
        this.resultViewName = name;
    }

    this.SetSortOrder = function (name) {
        this.sortOrder = name;
    }

    this.CreateNavigator = function (id, selectedCount, selected, options) {
        var uniqueID = this._GetNavigatorID(id);
        this.items[uniqueID] = new MWNavigator(id, selectedCount, selected, options);
    }

    this.SelectNavigatorValue = function (id, value) {
        this.ClearCriteriaField(id);

        var uniqueID = this._GetNavigatorID(id);
        this.items[uniqueID].SelectValue(value);
        if ((this.maximumNavigatorCriteriaSize > 0) && (this.ToString().length > this.maximumNavigatorCriteriaSize)) {
            this.items[uniqueID].DeselectValue(value);
            return false;
        }
        return true;
    }

    this.DeselectNavigatorValue = function (id, value) {
        var uniqueID = this._GetNavigatorID(id);
        this.items[uniqueID].DeselectValue(value);
    }

    this.SetCriteria = function (id, value, obj) {
        this.ClearCriteriaField(id);

        var uniqueID = this._GetCriteriaID(id);
        this.items[uniqueID] = new MWCriteria(id, value, obj);
    }

    this.DeleteCriteria = function (id) {
        var uniqueId = this._GetCriteriaID(id);
        delete this.items[uniqueId];
    }

    this.SetInitialValue = function (id, value) {
        var uniqueID = this._GetInitialValueID(id);
        this.items[uniqueID] = new MWInitialValue(id, value);
    }

    this.DeleteInitialValue = function (id) {
        var uniqueID = this._GetInitialValueID(id);
        delete this.items[uniqueID];
    }

    this.SetFieldsToClear = function (id, value) {
        this.fieldsToClear[id] = value;
    }

    this.ClearCriteriaField = function (id) {
        if (this.fieldsToClear[id] != undefined) {
            var fields = this.fieldsToClear[id];
            for (var i = 0; i < fields.length; i++) {
                this.itemsToDelete[this.itemsToDelete.length] = fields[i];
            }
        }
    }

    this.RemoveItemsToDelete = function () {
        for (var i = 0; i < this.itemsToDelete.length; i++) {
            delete this.items[this.itemsToDelete[i]];
        }
    }

    this.RemoveAllNavigatorsAndCriteria = function () {
        for (var uniqueID in this.items) {
            delete this.items[uniqueID];
        }
    }

    this.ToString = function () {
        var txt = this.QueryParamToString();
        var params = this.ParamToString();
        if (params.length > 0) {
            if (txt.length > 0) {
                txt += "&";
            }
            txt += "params=" + params;
        }
        return (txt.length == 0) ? "" : txt;
    }

    this.QueryParamToString = function () {
        // Result view must be first item
        var txt = this._GetValue("RV", this.resultViewName)
            + this._GetValue("SO", this.sortOrder)
            + this._GetValue("PN", this.pageNumber)
            + this._GetValue("PS", this.pageSize);
        for (var uniqueID in this.items) {
            var object = this.items[uniqueID];
            if (object.HasValue && object.HasValue()) {
                txt += "|" + uniqueID + ":" + object.ToString();
            }
        }
        return (txt.length == 0) ? "" : base64.encode("v0.1" + txt + "|" + "v0.1");
    }

    this.ParamToString = function () {
        var params = "";
        for (var key in this.additionalQSParams) {
            params += (params.length == 0 ? "" : "|") + key + ":" + this.additionalQSParams[key];
        }
        return (params.length == 0) ? "" : base64.encode(params);
    }

    this.GetCriteria = function (id) {
        var uniqueID = this._GetCriteriaID(id);
        return this.items[uniqueID];
    }

    this.Escape = function (value) {
        return new String(value).replace(/\|/g, "&mwenc1;").replace(/:/g, "&mwenc2;").replace(/_/g, "&mwenc3;").replace(/=/g, "&mwenc4;");
    }

    this._GetValue = function (id, value) {
        return (value == "") ? "" : "|" + id + ":" + value;
    }

    this._GetNavigatorID = function (id) {
        return "NA:" + id;
    }

    this._GetCriteriaID = function (id) {
        return "CR:" + id;
    }

    this._GetInitialValueID = function (id) {
        return "IV:" + id;
    }
}



// Navigator object
function MWNavigator(id, selectedCount, selected, options) {
    this.id = id;
    this.selectedCount = selectedCount;
    this.selected = selected;
    this.options = options;

    this.SelectValue = function (value) {
        this.selected[value] = this.options[value];
        this.selectedCount++;
    }

    this.DeselectValue = function (value) {
        delete this.selected[value];
        this.selectedCount--;
    }

    this.HasValue = function () {
        return (this.selectedCount > 0);
    }

    this.ToString = function () {
        var txt = "";
        for (var id in this.selected) {
            if (txt != "")
                txt += "_";
            txt += query.Escape(id) + "_" + query.Escape(this.selected[id]);
        }
        return txt;
    }
}



// Criteria object
function MWCriteria(id, value, obj) {
    this.id = id;
    this.value = value;
    this.obj = obj;

    this.HasValue = function () {
        if (this.obj && this.obj.hasClassName('hintShown'))
            return false;

        return (this.value.length > 0);
    }

    this.ToString = function () {
        return query.Escape(this.value);
    }
}



// Initial value object
function MWInitialValue(id, value) {
    this.id = id;
    this.value = value;

    this.HasValue = function () {
        return (this.value.length > 0);
    }

    this.ToString = function () {
        return this.value;
    }
}



// Navigator event
function NavigatorOnClick(obj, id) {
    // Ignore clicks on non-items
    if (obj.selectedIndex < 0)
        return false;

    // Add value
    if (!query.SelectNavigatorValue(id, obj[obj.selectedIndex].value)) {
        alert(QueryText["LimitText"]);
        return false;
    }

    // Go to first page
    query.SetPageNumber("");

    // Perform search
    PerformSearch();
}



// Navigator event
function NavigatorLinksOnClick(NavigatorId, value) {
    // Ignore clicks on non-items
    if (value == null || value == "")
        return false;

    // Add value
    if (!query.SelectNavigatorValue(NavigatorId, value)) {
        alert(QueryText["LimitText"]);
        return false;
    }

    // Go to first page
    query.SetPageNumber("");

    // Perform search
    PerformSearch();
}




//Crieteria value event, removes the criteria from the Items list
function CriteriaValueOnClick(obj, id) {
    //remove criteria
    query.DeleteCriteria(id);

    //remove initial value
    query.DeleteInitialValue(id);

    //go to first page
    query.SetPageNumber("");

    //Perform search
    PerformSearch();
}



//Criteria select event, adds the criteria to the items list
function CriteriaOnClick(id, value, initialValue) {
    query.SetCriteria(id, value);

    if ((initialValue != undefined) && (initialValue != null) && (initialValue != "")) {
        query.SetInitialValue(id, initialValue);
    }

    query.SetPageNumber("");

    PerformSearch();
}



// Search button event
function SearchButtonOnClick(obj) {
    // Clear all criterias
    query.RemoveAllNavigatorsAndCriteria();

    // Go to first page
    query.SetPageNumber("");

    // Perform search
    PerformSearch(obj);
}



// Geo search event
function GeoSearchSearch(id, criteria, address) {
    // Set the initial value address in the query
    query.SetInitialValue(id, address);

    // Add the criteria to the querqies criteria list
    query.SetCriteria(id, criteria);

    // Perform search
    PerformSearch();
}



// Reset button event
function ResetSearchOnClick(obj) {
    // Clear criteria
    query.RemoveAllNavigatorsAndCriteria();

    // Go to first page
    query.SetPageNumber("");

    // Perform search without updating criteria
    PerformSearchWithoutUpdatingCriteria();
}



// Result view event
function ResultViewOnClick(name) {
    // Set result view
    query.SetResultView(name);

    // Go to page 1 and resize page
    query.SetPageNumber("");
    query.SetPageSize("");

    // Perform search
    PerformSearch();
}



// Sort order event
function SortOrderOnClick(name) {
    // Set sort order
    query.SetSortOrder(name);

    // Perform search
    PerformSearch();
}



// Page size event
function PageSizeOnClick(value) {
    // Go to page 1 and resize page
    query.SetPageNumber("");
    query.SetPageSize(value);

    // Perform search
    PerformSearch();
}



// Go to page event
function GoToPageOnClick(value) {
    // Go to page
    query.SetPageNumber(value);

    // Perform search
    PerformSearch();
}



// Go to first page event
function GoToFirstPageOnClick() {
    // Move
    query.SetPageNumber(1);

    // Perform search
    PerformSearch();
}



// Go to last page event
function GoToLastPageOnClick() {
    // Move
    query.SetPageNumber(query.maxPageNumber);

    // Perform search
    PerformSearch();
}



// Go to next page event
function GoToNextPageOnClick() {
    // Move
    query.SetPageNumber(query.pageNumber + 1);

    // Perform search
    PerformSearch();
}



// Go to previous page event
function GoToPreviousPageOnClick() {
    // Move
    query.SetPageNumber(query.pageNumber - 1);

    // Perform search
    PerformSearch();
}



// Method for getting querystring
function GetQuerystring(action) {
    // Make sure all criteria are up-to-date
    SetAllCriteria();

    // Return new action
    return add_to_url(action, "query", query.ToString());
}



// Method for performing search
function PerformSearch(obj) {
    // Make sure all criteria are up-to-date
    SetAllCriteria();

    // Make sure the freetext criteria does not contain the default text
    var freetextCriteria = query.GetCriteria('Freetext');
    var freetextInput = freetextCriteria.obj;
    freetextInput.value = (freetextInput.value == freetextInput.title) ? '' : freetextInput.value;
    freetextCriteria.value = freetextInput.value;

    // Remove the items that have been added for deletion by other search fields
    query.RemoveItemsToDelete();

    // Start on first page
    query.SetPageNumber("");

    // Get URL
    var url = query.resultPage;

    // Add SEO-like text
    if (freetextCriteria.HasValue()) {
        var text = escape(freetextCriteria.ToString().replace(/"/g, '').replace(/'/g, '').replace(/ /g, '+'));
        url = add_to_url(url, "soegeord", text);
    }

    // Add company id to request if it's needed
    if (query.compid != undefined) {
        url = add_to_url(url, "compid", query.compid);
    }

    // Perform search
    document.location.href = add_to_url(url, "query", query.ToString());
    return false;
}



// Search button event
function OfirSearchButtonOnClick(obj) {
    // Make sure all criteria are up-to-date
    SetAllCriteria();

    // Make sure the freetext criteria does not contain the default text
    var freetextCriteria = query.GetCriteria('Freetext');
    var freetextInput = freetextCriteria.obj;
    freetextInput.value = (freetextInput.value == freetextInput.title) ? '' : freetextInput.value;
    freetextCriteria.value = freetextInput.value;

    // Reset all
    query.RemoveAllNavigatorsAndCriteria();

    // Add "Freetext" criteria
    if (freetextCriteria.value) {
        query.SetCriteria(freetextCriteria.id, freetextCriteria.value, freetextCriteria.obj);
    }

    // Start on first page
    query.SetPageNumber("");

    // Get URL
    var url = query.resultPage;

    // Add SEO-like text
    if (freetextCriteria.HasValue()) {
        var text = escape(freetextCriteria.ToString().replace(/"/g, '').replace(/'/g, '').replace(/ /g, '+'));
        url = add_to_url(url, "soegeord", text);
    }

    // Add company id to request if it's needed
    if (query.compid != undefined) {
        url = add_to_url(url, "compid", query.compid);
    }

    // Perform search
    document.location.href = add_to_url(url, "query", query.ToString());
    return false;
}
