Array.prototype.contains = function (element) {
          for (var i = 0; i < this.length; i++) 
       {
              if (this[i] == element) 
          {
                      return true;
              }
          }
          return false;
  };

// define addNamespace utility function if not already present
if (typeof(addNamespace) == "undefined") {
    addNamespace = function(namespace) {
	var o = window;
	var d = namespace.split(".");

	for (var j=0 ; j<d.length; j=j+1) {
		o[d[j]] = o[d[j]] || {};
		o = o[d[j]];
	}
    }; 
}

addNamespace("accedobroadband.querystring");

// reset excluded parameters
accedobroadband.querystring.excludes = null;
accedobroadband.querystring.keyValuePairs = null;

accedobroadband.querystring.init = function() {
	this.getAllParameters();
};


accedobroadband.querystring.getAllParameters = function() {               
        var url = null;
        var index = window.location.href.indexOf("?");
        
        if (index !== -1) {
            // was questionmark last character in string?
            if (index !== (window.location.href.length-1)) {
              url = window.location.href.substring(index+1);    
            }            
        }
                
        // check for no param case        
        if (url === null) {
            this.keyValuePairs = [];
        } else {        
          this.keyValuePairs = url.split("&");    	
        }
};

accedobroadband.querystring.getValue = function(_key) {
	var key, value;      
                      
	for (var param=0; param < this.keyValuePairs.length; param++) {	
	    key = this.keyValuePairs[param].split("=")[0];
	    if (key == _key) {
		value = this.keyValuePairs[param].split("=")[1];	    
		this.lastIndex = param;
		return value;
	    }
	}
        
	// no value found for specified key
	this.lastIndex = null;
	return null;
};

accedobroadband.querystring.parameters = function(a) {
	
	/* a = array of either:
	 *	- a string (without =-sign) indicating that this key should not be included in the parameters list
	 * or   - a key/value pair (a=b) indicating that this pair should appear in the parameters results 
	 */
              
	 var params;
         
         // populate params with values if they exist
         if (this.keyValuePairs === null) {
            params = [];
         } else {
            params = this.keyValuePairs.slice(0);
         }
         
	 var excludes = [];
	 var includes = [];

	if (a != null) {
	  // iterate array and find relevant entries
	  for (var j=0; j < a.length; j++) {
		if (a[j].indexOf("=") == -1) {
		    excludes.push(a[j]);
		} else {
			// overwrite existing parameter (if it exists)
			if (this.getValue(a[j].split("=")[0])) {
				params[this.lastIndex] = a[j];
			} else {
				params.push(a[j]);
			}
		}
	  }
	} 	
		
	var additionalParams = "";
 	for (var i=0; i < params.length; i++) {	
	    var key = params[i].split("=")[0];
	    var value = params[i].split("=")[1];

	    if (!excludes.contains(key)) {
		// this is not a reserved parameter so include it in list
 	    	additionalParams += key+"="+value+"&";
	    }
 	}

 	var lengthOfParams = additionalParams.length;
 	if (lengthOfParams > 0) {
	    additionalParams = additionalParams.substring(0, additionalParams.length-1);    
	}

	return additionalParams;
};



/**
 * Instantiates the given querystring parameter in a given scope.
 *
 * <ul>
 *   <li>If no scope is given, the global window scope will be used.</li>
 *   <li>If the variable is already declared, it will <b>not</b> be
 *       overwritten.</li>
 * </ul>
 *
 * @param key [String] the name of the value you want to use
 * @param scope [Object] the scope in which to instantiate the variables
 * @return [Object] the scope supplied, so that one can assign new scopes
 *                  by calling this method as such:
 *                  <pre>
 *                    var myScope = accb.quers.useValue('lang', {});
 *                  </pre>
 *                  <p>
 *                    This means we can access the querystring variable
 *                    as such:
 *                  </p>
 *                  <pre>
 *                    myScope.lang;
 *                  </pre>
 */
accedobroadband.querystring.useValue = function(key, scope){
    // If no scope declared, presume global
    if (typeof(scope) === 'undefined'){
        scope = window;
    }
    
    // If it already exists, don't overwrite it!
    // We would risk overwriting some important values in
    // e.g. window if we did allow that.
    if (typeof(scope[key]) === 'undefined'){
        scope[key] = this.getValue(key);
    }
    
    return scope;
};


/**
 * Instantiates all querystring parameters in a given scope.
 *
 * <ul>
 *   <li>If no scope is given, the global window scope will be used.</li>
 *   <li>If a variable is already declared, it will <b>not</b> be
 *       overwritten.</li>
 * </ul>
 *
 * @param values [Array of String] the values you want to use, send null 
 *                                 or empty array to get all parameters. 
 * @param scope [Object] the scope in which to instantiate the variables
 * @return [Object] the scope supplied, so that one can assign new scopes
 *                  by calling this method as such:
 *                  <pre>
 *                    var myScope = accb.quers.useValues(['lang', 'score'], {});
 *                  </pre>
 *                  <p>
 *                    This means we can access the querystring variables
 *                    as such:
 *                  </p>
 *                  <pre>
 *                    myScope.lang;
 *                    myScope.score;
 *                  </pre>
 */
accedobroadband.querystring.useValues = function(values, scope){
    // If no scope declared, assume global
    if (typeof(scope) === 'undefined'){
        scope = window;
    }
    
    for (var i = 0; i < this.keyValuePairs.length; i++){
        var key = this.keyValuePairs[i].split("=")[0];
        var value = this.keyValuePairs[i].split("=")[1];
        
        // If the variable already exists, don't overwrite it!
        // We would risk overwriting some important values in
        // e.g. window if we did allow that.
        if (typeof(scope[key]) === 'undefined'){
            if (typeof(values) === 'undefined' || values === null || values.length === 0 || values.contains(key)){
                scope[key] = value;
            }
        }
    }
    
    return scope;
};


accedobroadband.querystring.init();

