﻿var hashSerializer = new function () {
    this.site = '';
    this.vehicleSelection = '';
    this.vehicleParameters = [];
    this.dropDownIndicator = '';
    this.searchType = '';
    this.searchParameters = [];

    this.marineSearchTypeSelector = '';

    this.searchTypeIdx = 1;
    this.path = [];

    this.parseCarParameters = function () {
        if (this.hasVehicleSelection()) {
            this.vehicleSelection = this.path[1];
            this.parseCarVehicleParameters(this.path);
        }
        if (this.hasSearchParameters()) {
            this.parseCarSearchParameters(this.path);
        }
    };

    this.hasVehicleSelection = function () {
        return this.path[1] == 'code' || this.path[1] == 'reg' || this.path[1] == 'chassi';
    };

    this.parseCarVehicleParameters = function (path) {
        if (this.vehicleSelection == 'reg' || this.vehicleSelection == 'chassi') {
            this.vehicleParameters = [path[2]];
            this.searchTypeIdx = 3;
        }
        else if (this.vehicleSelection == 'code') {
            var firstParameterIdx = this.findFirstCarParameterIdx(path);
            this.vehicleParameters = [path[firstParameterIdx], path[firstParameterIdx + 1], path[firstParameterIdx + 2], path[firstParameterIdx + 3]];
            this.searchTypeIdx = firstParameterIdx + 4;
        }
        else {
            this.searchTypeIdx = 2;
        }
    };

    this.findFirstCarParameterIdx = function (path) {
        if (path[2] == 'dd0' || path[2] == 'dd1') {
            this.dropDownIndicator = path[2];
            return 3;
        }
        else {
            this.dropDownIndicator = '';
            return 2;
        }
    };

    this.hasSearchParameters = function () {
        return this.path[this.searchTypeIdx] != undefined;
    };

    this.parseCarSearchParameters = function (path) {
        this.searchType = path[this.searchTypeIdx];
        if (this.searchType != 'dropdown' && searchTypeIsGroupSearch(path[this.searchTypeIdx + 1])) {
            // search type is a group search, but the parameter at searchtypeidx is vehicle code
            this.vehicleParameters.push(this.searchType);
            this.searchType = "";
            this.searchParameters = path[this.searchTypeIdx + 2];
        }
        else if (searchTypeIsGroupSearch(this.searchType)) {
            this.searchType = "";
            this.searchParameters = path[this.searchTypeIdx];
        }
        else {
            this.searchParameters = path[this.searchTypeIdx + 1];
        }
    };

    searchTypeIsGroupSearch = function (searchType) {
        return searchType != undefined && (searchType.substr(0, 2) == "[\"" || searchType.startsWith("class"));
    }

    this.parseMarineParameters = function () {
        if (this.hasVehicleSelection()) {
            this.vehicleSelection = this.path[1];
            this.parseMarineVehicleParameters(this.path);
        }
        if (this.hasSearchParameters()) {
            this.parseMarineSearchParameters();
        }
    };

    this.parseMarineVehicleParameters = function () {
        this.dropDownIndicator = this.path[2];
        this.marineSearchTypeSelector = this.path[3];
        this.vehicleSelection = 'code';
        this.vehicleParameters = [this.path[4], this.path[5], this.path[6]];
        this.searchTypeIdx = 7;
    }

    this.parseMarineSearchParameters = function () {
        this.searchType = this.path[this.searchTypeIdx];
        if (this.searchType != 'dropdown' && searchTypeIsGroupSearch(this.path[this.searchTypeIdx + 1])) {
            this.vehicleParameters.push(this.searchType);
            this.searchType = "";
            this.searchParameters = this.path[this.searchTypeIdx + 1];
        }
        else if (searchTypeIsGroupSearch(this.path[this.searchTypeIdx])) {
            this.searchType = "";
            this.searchParameters = this.path[this.searchTypeIdx];
        }
        else {
            this.searchParameters = this.path[this.searchTypeIdx + 1];
        }
    }

    this.parseGulfOilParameters = function () {
        this.searchType = this.path[1];
        this.searchParameters = [this.path[2]];
    };

    this.parseInterchangeParameters = function () {
        this.searchType = this.path[1];
        this.searchParameters = [this.path[2]];
    };

    
    this.parseArtNrParameters = function () {
        this.searchType = this.path[1];
        this.searchParameters = [this.path[2]];
    };

    this.parseHash = function () {
        var decodedHash = recursiveDecodeURI(location.hash);
        this.path = decodedHash.substring(2).split('/');

        this.site = this.path[0];
        if (this.site == 'car') {
            this.parseCarParameters();
        }
        else if (this.site == 'marine') {
            this.parseMarineParameters();
        }
        else if (this.site == 'gulf') {
            this.parseGulfOilParameters();
        }
        else if (this.site == 'interchange') {
            this.parseInterchangeParameters();
        }
        else if (this.site == 'artnr') {
            this.parseArtNrParameters
        }
    };

    this.recursiveDecodeURI = function (uri) {
        var recurseCount = 20;
        do {
            uri = decodeURI(uri);
        } while (uri.indexOf("%") != -1 && recurseCount > 0)
        return uri;
    };

    this.updateValues = function (updateVars) {
        this.parseHash();
        if (updateVars.site != this.site) {
            // if we change site we reset the serializer
            this.resetHashSerializer();
        }
        var updateWithDefaults = this.extendUpdatesWithDefaults(updateVars);
        this.site = updateWithDefaults.site;
        this.vehicleSelection = updateWithDefaults.vehicleSelection;
        this.vehicleParameters = updateWithDefaults.vehicleParameters;
        this.dropDownIndicator = updateWithDefaults.dropDownIndicator;
        this.searchType = updateWithDefaults.searchType;
        this.searchParameters = updateWithDefaults.searchParameters;
        this.marineSearchTypeSelector = updateWithDefaults.marineSearchTypeSelector;
    }

    this.resetHashSerializer = function () {
        this.site = '';
        this.vehicleSelection = '';
        this.vehicleParameters = [];
        this.dropDownIndicator = '';
        this.searchType = '';
        this.searchParameters = [];
        this.marineSearchTypeSelector = '';
    }

    this.extendUpdatesWithDefaults = function (updateVars) {
        return $.extend({
            site: this.site,
            vehicleSelection: this.vehicleSelection,
            vehicleParameters: this.vehicleParameters,
            dropDownIndicator: this.dropDownIndicator,
            searchType: this.searchType,
            searchParameters: this.searchParameters,
            marineSearchTypeSelector: this.marineSearchTypeSelector
        }, updateVars);
    }

    this.setURLHash = function () {
        var siteHashString = this.createSiteHash();
        if (siteHashString != '') {
            var hashString = "/" + siteHashString;
            location.hash = hashString;
        }
        return siteHashString;
    }

    this.createSiteHash = function () {
        if (this.site == 'car') {
            return this.createCarHash();
        }
        else if (this.site == 'marine') {
            return this.createMarineHash();
        }
        else if (this.site == 'gulf') {
            return this.createGulfHash();
        }
        else if (this.site == 'interchange') {
            return this.createInterchangeHash();
        }
        else if (this.site == 'artnr') {
            return this.createArtNrHash();
        }
        return '';
    }

    this.createCarHash = function () {
        var urlPartArray = new Array();
        urlPartArray.push(this.site);
        if (this.vehicleSelection != '')
            urlPartArray.push(this.vehicleSelection);
        if (this.dropDownIndicator != '')
            urlPartArray.push(this.dropDownIndicator);
        if (this.vehicleParameters.length > 0)
            urlPartArray.push(this.vehicleParameters.join("/"));
        var searchString = this.createSearchString();
        if (searchString != '')
            urlPartArray.push(searchString);
        return urlPartArray.join("/");
    }

    this.createSearchString = function () {
        var searchString = ((this.searchType != "") ? this.searchType + "/" : "");
        if (this.searchParameters.length == 1) {
            searchString += this.searchParameters[0];
        }
        else if (this.searchParameters.length > 1) {
            searchString += urlFriendlyStringify(this.searchParameters);
        }
        return searchString;
    }

    this.createMarineHash = function () {
        var urlPartArray = new Array();
        urlPartArray.push(this.site);
        if (this.vehicleSelection != '')
            urlPartArray.push(this.vehicleSelection);
        if (this.dropDownIndicator != '')
            urlPartArray.push(this.dropDownIndicator);
        if (this.marineSearchTypeSelector != '')
            urlPartArray.push(this.marineSearchTypeSelector);
        if (this.vehicleParameters.length > 0)
            urlPartArray.push(this.vehicleParameters.join("/"));
        var searchString = this.createSearchString();
        if (searchString != '')
            urlPartArray.push(searchString);
        return urlPartArray.join("/");
    }

    urlFriendlyStringify = function (array) {
        if (array == undefined || array.length == 0) {
            return "";
        }
        var arrayString = JSON.stringify(array);
        return arrayString.substr(1, arrayString.length - 2).replace(/\\/g, "");
    }

    this.createGulfHash = function () {
        return [this.site, this.searchType, this.searchParameters[0]].join("/");
    };

    this.createInterchangeHash = function () {
        return [this.site, this.searchType, this.searchParameters[0]].join("/");
    };

    this.createArtNrHash = function () {
        return [this.site, this.searchType, this.searchParameters[0]].join("/");
    };

}
