﻿/**
 * The class contains methods for parsing query string.
 */
var Query = {
    /**
     * Retrieves the current query.
     *
     * @return The current query.
     */
    getCurrentQuery: function() {
        return Query.getQuery(top.location.href.toString());
    },

    /**
     * Retrieves the query string from an URL.
     *
     * @return The query from the passed URL.
     */
    getQuery: function(url) {
        var firstQuery = ((url.match(/\?/)) ? url.replace(/^[^\?]+\??([^#]*).*$/, '$1') : '').replace(/\?/, '');
        var secondQuery = Query.getDynamicQuery(url);
        
        return Query.combineQuery(firstQuery, secondQuery);
    },
    
    /**
     * Extracts dynamic query from the query string.
     *
     * @param url location href.
     * @return The query from the location href.
     */
    getDynamicQuery: function(url) {
        return ((url.match(/#/)) ? url.replace(/^[^#]+#?(.*)$/, '$1') : '').replace(/#/, '');
    },
    
    /**
     * Splits the query string to a list of parameters.
     *
     * @param query Query string.
     */
    getQueryParams: function(query) {
        var result = new Object();
        
        if (query != undefined) {
            query = query.toString();
            var paramsAndNames = query.split(/\&/);
            for (var i = 0; i < paramsAndNames.length; i++) {
                var nameValue = paramsAndNames[i].split(/=/);
                if (nameValue != undefined && nameValue.length > 1) {
                    result[nameValue[0]] = nameValue[1];
                }
            }
        }
        
        return result;
    },
    
    /**
     * Combines two query strings.
     *
     * @param firstQuery first query string.
     * @param secondQuery second query string.
     */
    combineQuery: function(firstQuery, secondQuery) {
        var firstParams = Query.getQueryParams(firstQuery);
        var secondParams = Query.getQueryParams(secondQuery);
        for (var paramName in secondParams) firstParams[paramName] = secondParams[paramName];
        
        var query = '';
        for (var paramName in firstParams) {
            if (query.length > 0) query = query.concat('&');
            query = query.concat(paramName).concat('=').concat(firstParams[paramName]);
        }
        
        return query;
    },
    
    /** 
     * Generates a new query string based on the current with
     * new parameters.
     *
     * @param query Current query.
     * @param newParams Array of pairs (name, value) of new parameters.
     */
    generateQueryString: function(query, newParams) {
        if (newParams != undefined) {
            for (var paramName in newParams) {
                var re = new RegExp('(^|\&)'.concat(paramName.escapeRegExp()).concat('=[^\&]*($|\&)'),'g');
                query = query.replace(re, '$2').replace(/^\&/, '');
                if ($defined(newParams[paramName])) {
                    if (query.length > 0) {
                        query += '&';
                    }
                    query += encodeURIComponent(paramName).concat('=').concat(encodeURIComponent(newParams[paramName]));
                }
            };
            
            return query;
        } else {
            return null;
        }
    },
    
    /**
     * Retrives a parameter from the query string.
     *
     * @param query The query string.
     * @param paramName Name of the parameter to be retrieved.
     */
    getParameterFromQueryString: function(query, paramName) {
        var re = new RegExp('^.*(^|\&)'.concat(paramName.escapeRegExp()).concat('=([^\&]*)($|\&.*$)'),'');
        if (re.test(query))
            return decodeURIComponent(query.replace(re, '$2').replace(/\+/g, ' '));
        else
            return null;
    },
    
    /**
     * Removes reduntant parameters from the query.
     *
     * @param query The query string.
     */
    removeRedundantParamsFromQuery: function(query) {
        var locationHref = top.location.href.toString();
        var mainQuery = ((locationHref.match(/\?/)) ? locationHref.replace(/^[^\?]+\??([^#]*).*$/, '$1') : '').replace(/\?/, '');
        
        var mainParams = Query.getQueryParams(mainQuery);
        var params = Query.getQueryParams(query);
        
        var query = '';
        for (var paramName in params) {
            if (mainParams[paramName] != params[paramName]) {
                if (query.length > 0) query = query.concat('&');
                query = query.concat(paramName).concat('=').concat(params[paramName]);
            }
        }
        
        // Adding those parameters that don't exist in the new query.
        for (var paramName in mainParams) {
            if (!$defined(params[paramName])) {
                if (query.length > 0) query = query.concat('&');
                query = query.concat(paramName).concat('=');
            }
        }
        
        return query;
    }
    
};

// Checking whether the page should be redirected.
params = Query.getDynamicQuery(location.href.toString()).replace(/\s+$/,'');
if (params.length > 0) {
    location.href = '?'.concat(Query.getCurrentQuery());
}
