/**
	This file contains the Hashtable implementation definition (data structure and methods), 
	Home Page JavaScript Objects declarations, and Home Page Hashtable data structure declarations.
*/


/**
    Created by: Michael Synovic
    on: 01/12/2003
   
    This is a Javascript implementation of the Java Hashtable object.
   
    Contructor(s):
     Hashtable()
              Creates a new, empty hashtable
   
    Method(s):
     void clear()
              Clears this hashtable so that it contains no keys.
     boolean containsKey(String key)
              Tests if the specified object is a key in this hashtable.
     boolean containsValue(Object value)
              Returns true if this Hashtable maps one or more keys to this value.
     Object get(String key)
              Returns the value to which the specified key is mapped in this hashtable.
     boolean isEmpty()
              Tests if this hashtable maps no keys to values.
     Array keys()
              Returns an array of the keys in this hashtable.
     void put(String key, Object value)
              Maps the specified key to the specified value in this hashtable. 
              A NullPointerException is thrown is the key or value is null.
     Object remove(String key)
              Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
     int size()
              Returns the number of keys in this hashtable.
     String toString()
              Returns a string representation of this Hashtable object in the form of a set of entries, 
              enclosed in braces and separated by the ASCII characters ", " (comma and space).
     Array values()
              Returns a array view of the values contained in this Hashtable.
           
*/
	/**
		Constructor to instantiate an Hashtable object with the 
		internal Array data structure and methods defined on it.
	*/
	function Hashtable(){
	    this.clear = hashtable_clear;
	    this.containsKey = hashtable_containsKey;
	    this.containsValue = hashtable_containsValue;
	    this.get = hashtable_get;
	    this.isEmpty = hashtable_isEmpty;
	    this.keys = hashtable_keys;
	    this.put = hashtable_put;
	    this.remove = hashtable_remove;
	    this.size = hashtable_size;
	    this.toString = hashtable_toString;
	    this.values = hashtable_values;
	    this.hashtable = new Array();
	}
	
	/** Method to delete all the contents of the current hash table instance. */
	function hashtable_clear(){
	    this.hashtable = new Array();
	}
	
	/** Method to check if the specified key exists in the current hash table instance. 
		Returns true/false. */
	function hashtable_containsKey(key){
	    var exists = false;
	    for (var i in this.hashtable) {
	        if (i == key && this.hashtable[i] != null) {
	            exists = true;
	            break;
	        }
	    }
	    return exists;
	}
	
	/** Method to check if the specified value(object) is present in the current hashtable instance.
		Returns true/false.
	*/
	function hashtable_containsValue(value){
	    var contains = false;
	    if (value != null) {
	        for (var i in this.hashtable) {
	            if (this.hashtable[i] == value) {
	                contains = true;
	                break;
	            }
	        }
	    }
	    return contains;
	}
	
	/**	Method to get the value (object) for the specified key from the current hashtable instance.
		Returns the value (object).		
	*/
	function hashtable_get(key){
	    return this.hashtable[key];
	}
	
	/** Method to check if the current hahstable instance is empty.<br> 
		Returns true/false.	
	*/
	function hashtable_isEmpty(){
	    return (parseInt(this.size()) == 0) ? true : false;
	}
	
	/** Method to return an Array of all the keys in the current hashtable instance.	
	*/
	function hashtable_keys(){
	    var keys = new Array();
	    for (var i in this.hashtable) {
	        if (this.hashtable[i] != null)
	            keys.push(i);
	    }
	    return keys;
	}
	
	/**	Method to create an entry (key=value) in the current hashtable instance.
	*/
	function hashtable_put(key, value){
	    if (key == null || value == null) {
	        throw "NullPointerException {" + key + "},{" + value + "}";
	    }else{
	        this.hashtable[key] = value;
	    }
	}
	
	/**	Method to remove an entry specified by the key from the current hashtable instance.
		Returns the removed value (object).
	*/
	function hashtable_remove(key){
	    var rtn = this.hashtable[key];
	    this.hashtable[key] = null;
	    return rtn;
	}
	
	/** Method to return the size (no of entries) of the current hashtable instance.		
	*/
	function hashtable_size(){
	    var size = 0;
	    for (var i in this.hashtable) {
	        if (this.hashtable[i] != null)
	            size ++;
	    }
	    return size;
	}
	
	/**	Method to return a string containing the {key, value} 
		pair for all the entries of the current hashtable instance.
	*/
	function hashtable_toString(){
	    var result = "";
	    for (var i in this.hashtable)
	    {     
	        if (this.hashtable[i] != null)
	            result += "{" + i + "},{" + this.hashtable[i] + "}\n";  
	    }
	    return result;
	}
	
	/**	Method to return an Array of all values (objects) 
		of the current hashtable instance.	
	*/
	function hashtable_values(){
	    var values = new Array();
	    for (var i in this.hashtable) {
	        if (this.hashtable[i] != null)
	            values.push(this.hashtable[i]);
	    }
	    return values;
	}


	/**************************** Begin Declartion of JS objects ***********************************/

	/** Product family object.
			name_							: name of the product family, array of TRANSLATED_FIELD objects.
			variable_name_					: variable name of the product family
			selector_punchins_array_		: array of _BM_SEARCH_FLOW_PAGE_PUNCHIN and _BM_SEARCH_RESULTS_PAGE_PUNCHIN objects 
											  corresponding to the product family's defined selector punch-ins.
	*/	
	function _BM_PRODUCT_FAMILY( 	name_,
									variable_name_,
									selector_punchins_array_) {
		this.name 						= name_;
		this.variable_name				= variable_name_;
		this.selector_punchins_array	= selector_punchins_array_;
	}
	
	/** Product line object.
			name_							: name of the product line, array of TRANSLATED_FIELD objects.
			variable_name_					: variable name of the product line
			description_					: pline description
			custom_attr_array_				: array of custom attribute objects of the product line.
			file_attachements_array_		: array of all the file attachement attributes (_BM_FILE_ATTACHMENT_ATTR instances)
			associated_files_array_			: array of _BM_ASSOCIATED_FILE objects of the product line.
			selector_punchins_array_		: array of _BM_SEARCH_FLOW_PAGE_PUNCHIN and _BM_SEARCH_RESULTS_PAGE_PUNCHIN objects 
											  corresponding to the product line's defined selector punch-ins.
	*/	
	function _BM_PRODUCT_LINE(	name_,
								variable_name_,
								description_,
								custom_attr_array_,
								file_attachments_array_,
								associated_files_array_,
								selector_punchins_array_) {
		this.name						= name_;
		this.variable_name				= variable_name_;
		this.description				= description_;
		this.custom_attr_array			= custom_attr_array_;
		this.file_attachments_array		= file_attachments_array_;
		this.associated_files_array		= associated_files_array_;
		this.selector_punchins_array	= selector_punchins_array_;
	}
	
	/** Model object.
			name_						: name of the model, array of TRANSLATED_FIELD objects.
			variable_name_				: variable name of the model
			description_				: model description
			custom_attr_array_			: array of custom attribute objects of the product line.
			file_attachements_array_	: array of all the file attachement attributes (_BM_FILE_ATTACHMENT_ATTR instances)
			associated_files_array_		: array of _BM_ASSOCIATED_FILE objects of the model. 
			config_punchins_array_		: array of _BM_MODEL_CONFIG_PAGE_PUNCHIN objects corresponding to the model?s 
									  	  defined model config page punchins.
	*/	
	function _BM_MODEL(	name_,
						variable_name_,
						description_,
						custom_attr_array_,
						file_attachments_array_,
						associated_files_array_,
						config_punchins_array_) {

		this.name 					= name_;
		this.variable_name			= variable_name_;
		this.description			= description_;
		this.custom_attr_array		= custom_attr_array_;
		this.file_attachments_array	= file_attachments_array_;
		this.associated_files_array	= associated_files_array_;
		this.config_punchins_array	= config_punchins_array_;
	}
	
	/** Selector search results page punch-in object
		name_						: name of the punch-in
		variable_name_				: variable_name of the punch-in
		url_						: base URL for the punch-in
		status_						: status
		segment_id_					: segment id
		search_group_id_			: id of the search flow group
		search_group_var_name_		: variable_name of the search flow group
		pline_id_					: Id of the product line (if pline level punch-in)
		_bm_search_flow_config_atts_: Array of _BM_ATTR objects corresponding to input attributes for flow selection 
									  ("+" separated).
		_bm_atts_					: Array of _BM_ATTR objects corresponding to free floating attributes.
	*/
	function _BM_SEARCH_RESULTS_PAGE_PUNCHIN(	name_,
												variable_name_,
												order_number_,		
												url_,
												status_,
												_segment_id_,
												_pline_id_,
												search_group_id_,
												search_group_var_name_,
												_bm_search_flow_config_atts_,
												_bm_atts_) {
		this.name						= name_;
		this.variable_name				= variable_name_;
		this.order_number				= order_number_;
		this.url						= url_;
		this.status						= status_;
		this.segment_id					= _segment_id_;
		this.pline_id					= _pline_id_;
		this.search_group_id			= search_group_id_;
		this.search_group_var_name		= search_group_var_name_;
		this._bm_search_flow_config_atts= _bm_search_flow_config_atts_;
		this._bm_atts					= _bm_atts_;
	}

	/** Selector configuration page punch-in object
		name_						: name of the punch-in
		variable_name_				: variable_name of the punch-in
		url_						: URL for the punch-in
		segment_id_					: segment id
		search_group_id_			: id of the search flow group
		search_group_var_name_		: variable_name of the search flow group
		pline_id_					: Id of the product line (if pline level punch-in)
		_bm_search_flow_config_atts_: Array of _BM_ATTR objects corresponding to input attributes for flow selection ("+" separated).
		_bm_atts_					: Array of _BM_ATTR objects corresponding to free floating attributes.
	*/
	function _BM_SEARCH_FLOW_PAGE_PUNCHIN(	name_,
											variable_name_,
											order_number_,		 
											url_,
											status_,
											_segment_id_,
											_pline_id_,
											search_group_id_,
											search_group_var_name_,
											_bm_search_flow_config_atts_,
											_bm_atts_) {
								
		this.name						= name_;
		this.variable_name				= variable_name_;
		this.order_number				= order_number_;
		this.url						= url_;
		this.status						= status_;
		this.segment_id					= _segment_id_;
		this.pline_id					= _pline_id_;
		this.search_group_id			= search_group_id_;
		this.search_group_var_name		= search_group_var_name_;
		this._bm_search_flow_config_atts= _bm_search_flow_config_atts_;
		this._bm_atts					= _bm_atts_;
	}

	/** Model Configuration page punch-in object
		name_						: name of the punch-in
		variable_name_				: variable name of the punch-in
		url_						: URL for the punch-in
		product_family_var_name_	: variable name of the product family
		product_line_var_name_		: variable name of the product line
		model_var_name_				: variable name of the model
		_bm_search_flow_config_atts_: Array of _BM_ATTR objects corresponding to input attributes for flow selection 
									  ("+" separated).
		_bm_search_result_			: Array of __ATTR objects
									  corresponding to attributes, which are selector recommendations ("@" separated).
		_bm_atts_					: Array of _BM_ATTR objects corresponding to free floating attributes.
	*/
	function _BM_MODEL_CONFIG_PAGE_PUNCHIN(	name_,
											variable_name_,
											order_number_,	
											url_,
											product_family_var_name_,
											product_line_var_name_,
											model_var_name_,
											_bm_search_flow_config_atts_,
											_bm_search_result_,
											_bm_atts_) {
	
		this.name						= name_;
		this.variable_name				= variable_name_;
		this.order_number				= order_number_;
		this.url						= url_;
		this.product_family_var_name	= product_family_var_name_;
		this.product_line_var_name		= product_line_var_name_;
		this.model_var_name				= model_var_name_;
		this._bm_search_flow_config_atts= _bm_search_flow_config_atts_;
		this._bm_search_result			= _bm_search_result_;
		this._bm_atts					= _bm_atts_;
	}
	
	/** Part-detail page punch-in object.
		name_			: punch-in name
		variable_name_	: punch-in variable name
		url_			: punch-in URL
		part_number_	: corresponding part number
		company_id_		: company id
	*/
	function _BM_PART_DETAIL_PAGE_PUNCHIN(	name_,
											variable_name_,
											order_number_,
											url_,
											part_number_,
											company_id_) {
		this.name			= name_;
		this.variable_name	= variable_name_;
		this.order_number	= order_number_;
		this.url			= url_;
		this.part_number	= part_number_;
		this.company_id		= company_id_;
	}
										
	/** Object representing a product line / model file attachment custom attribute.
			attr_var_name_	: variable_name of the file attachment attribute.
			file_name_		: name of the file
			path_			: link to the file
	*/
	function _BM_FILE_ATTACHMENT_ATTR(attr_var_name_, file_name_, path_){
		this.attr_var_name	= attr_var_name_;
		this.file_name		= file_name_;
		this.path			= path_;		
	}
	
	/** Object representing a product line / model currency custom attribute
			attr_var_name_		: variable name of the currency attribute
			currencies_array_	: array of _BM_ATTR objects
	*/
	function _BM_CURRENCY_ATTR(attr_var_name_, currencies_array_){
		this.attr_var_name		= attr_var_name_;
		this.currencies_array	= currencies_array_;
	} 
	
	/** Object representing a translated field.
			language_code_	: language code ("en", "fr", etc)
			value_			: corresponding value of the field for the language
	*/
	function _BM_TRANSLATED_FIELD(language_code_, value_){
		this.language_code	= language_code_;
		this.value			= value_;		
	}
	
	/** Object representing an attribute (config or product attributes).
			attr_var_name	: variable name of the attribute
			value_			: value of the attribute
	*/	
	function _BM_ATTR(attr_var_name_, value_) {
		this.attr_var_name	= attr_var_name_;
		this.value			= value_;
	}
	
	/** Object representing a product line or a model associated file information.
			name			: name of the associated file.
			readable_name	: readable name of the associated file.
			link			: link to the associated file path.
	*/
	function _BM_ASSOCIATED_FILE (name_, readable_name_, link_) {	
		this.name			= name_;
		this.readable_name 	= readable_name_;
		this.link			= link_;
	}

/**************************** End Declartion of JS objects ***********************************/

/**************************** Begin Declartion of Hashtable Data Structures *********************/

	if(!_BM_PRODUCT_FAMILIES_MAP){
		var _BM_PRODUCT_FAMILIES_MAP	= new Hashtable();
	}
	
	if(!_BM_PLINES_MAP){
		var _BM_PLINES_MAP				= new Hashtable();
	}
	
	if(!_BM_MODELS_MAP){
		var _BM_MODELS_MAP				= new Hashtable();
	}

/**************************** Begin Declartion of Hashtable Data Structures *********************/
