/**
*   @version $Id: paramSearch.js 451 2007-12-05 14:48:51Z piotrj $
*	@package frontend
*	@author piotrj
*/

/**--------------------------------------------------------------------
*	wyszukiwarka parametryczna
*---------------------------------------------------------------------*/

	/**
	* Global array PARAM_ARRAY that contains all param data MUST be provided!
	* Global variable EMPTY_OPTION_VALUE that contains first element name in param select MUST be provided!
	*/

	/**global array that contains product data*/
	var products = new Array();

	/**
	* Class used for managing parameter data
	* 
	* @param paramId       parameter id 
	* @param name          parameter name
	*/
	function ParameterObj( paramId, name )
	{
		this.id = paramId;              //parameter id
		this.valueCount = 0;            //number of parameter values
		this.valueId = new Array();     //array that contains specified parameter value ids
		this.valueIdIndex = new Array();
		this.useValues = 'undefined';   //determines using all values in parameter or any value in product search
		this.name = name;
		this.isParamVisible = true;
	}

	/**
	* Function used to add parameter value id
	* @param valueId       id of parameter value
	*/
	function ParameterObj_addValueId( valueId )
	{
		this.valueId[this.valueCount] = valueId;
		this.valueIdIndex[valueId] = valueId;
		this.valueCount++;
	}

	/**
	* Function used to get parameter name
	* @return string that contains parameter name
	*/
	function ParameterObj_getName( name )
	{
		return this.name;
	}

	/**
	* Function used to get parameter id
	* @return string that contains parameter id
	*/
	function ParameterObj_getId()
	{
		return this.id;
	}

	/**
	* Function used to check if parameter is visible
	* @return boolean true - if parameter is visible, false - otherwise
	*/
	function ParameterObj_isVisible()
	{
		return this.isParamVisible;
	}

	/**
	* Function sets parameter visible state
	* @param state         boolean that is true if parameter is visible, false - otherwise
	*/
	function ParameterObj_setVisible( state )
	{
		this.isParamVisible = state;
	}

	/**
	* Function checks if specified parameter fullfill search conditions specified by input parameter
	* Checks if parameters have same id, and compares parameters values.
	* If specified parameter must have all values provided by input parameter function checks if parameters have same values
	* If specified parameter must have any of inputed parameter values even only one value is enought to fullfill search conditions
	*
	* @param parameter     ParameterObj that contains search conditions
	*
	* @return boolean      true - specified parameter fullfills search conditions
	*                      false - specified parameter does not fullfill search conditions
	*/
	function ParameterObj_fullfill( parameter )
	{
		if( this.id != parameter.id )
		{
			return false;
		}
		if( parameter.useValues == 'all' )
		{
			var id = null;
			for( var i=0; i < parameter.valueId.length; i++ )
			{
				id = parameter.valueId[i];
				if( this.valueIdIndex.length <= id )
				{
					return false;
				}
				if( this.valueIdIndex[id] != id )
				{
					return false;
				}
			}
			return true;
		}
		if( parameter.useValues == 'any' )
		{
			for( var i=0; i < parameter.valueId.length; i++ )
			{
				id = parameter.valueId[i];
				if( this.valueIdIndex.length <= id )
				{
					continue;
				}
				if( this.valueIdIndex[id] == id )
				{
					return true;
				}
			}
			return false;
		}
	}

	/**
	* Function used for debug purposes.
	* Function shows parameter data in alert window
	* @param title         string that contains popup window title
	*/
	function ParameterObj_showData( title )
	{
		var text = 'Param id = ' + this.id + '\nValues:\n';
		for( var i = 0; i < this.valueId.length; i++ )
		{
			text += this.valueId[i] + ', ';
		}
		text += '\nUse values: ' + this.useValues;
		if( ( title != '' ) && ( title != 'undefined' ) && ( title != null ) )
		{
			text += '\nTitle: ' + title;
		}
		alert( text );
	}

	/**adding functions to prototype*/
	ParameterObj.prototype.addValueId = ParameterObj_addValueId;
	ParameterObj.prototype.isVisible = ParameterObj_isVisible;
	ParameterObj.prototype.setVisible = ParameterObj_setVisible;
	ParameterObj.prototype.getId = ParameterObj_getId;
	ParameterObj.prototype.getName = ParameterObj_getName;
	ParameterObj.prototype.fullfill = ParameterObj_fullfill;
	ParameterObj.prototype.showData = ParameterObj_showData;

	/**
	* Class used for managing product data
	* @param prodId       product id
	*/
	function ProductObj( prodId )
	{
		this.id = prodId;               //product id
		this.params = new Array();      //contains product parameters object
		this.paramCount = 0;            //parameters number
		this.found = true;              //determines if product fullfills search conditions
	}

	/**
	* Function used to add ParameterObj object to product
	* @param param instance of ParameterObj class
	*/
	function ProductObj_addParam( param )
	{
		this.params[param.id] = param;
		this.paramCount++;
	}

	/**
	* Function used to check if product fullfills search conditions defined by parameter paramToCheck
	* @param paramToCheck  instance of ParameterObj that contains search conditions
	*/
	function ProductObj_checkParam( paramToCheck )
	{
		var position = paramToCheck.id
		if( this.params.length >= position )
		{
			var param = this.params[position];
			if( typeof( param ) == 'object' )
			{
				if( param.fullfill( paramToCheck ) )
				{
					return;
				}
			}
		}
		
		this.found = false;
	}

	/**
	* Function checks if product fullfills search conditions.
	* Function checks only actual product state. State can change after parameters check
	* @return boolean      true - if product fullfills search conditions
	*                      false - if product does not fullfill search conditions
	*/
	function ProductObj_isFound()
	{
		return this.found;
	}

	/**
	* Function reset product state to start state
	*/
	function ProductObj_resetFound()
	{
		this.found = true;
	}

	//adding functions to prototype
	ProductObj.prototype.addParam = ProductObj_addParam;
	ProductObj.prototype.checkParam = ProductObj_checkParam;
	ProductObj.prototype.isFound = ProductObj_isFound;
	ProductObj.prototype.resetFound = ProductObj_resetFound;

	/**
	* Function used to copy search parameter div defined by id like 'paramSearchDiv_PARAMID_prototype' prototypes MUST be provided.
	* Function manages parameter select html object data
	* @param paramId       contains parameter id
	*/
	function showSearchParam( paramId )
	{
		var paramDiv = $( 'paramSearchDiv_' + paramId + '_prototype' ).cloneNode(true);
		paramDiv.id = 'paramSearchDiv_' + paramId;
		//paramDiv.name = 'paramSearchDiv_' + paramId;
		paramDiv.style.display = 'block';
		$( 'paramSearchPanelDiv' ).appendChild( paramDiv );
		manageParamSelect( paramId, true );
		countProducts();
		setParamDivHeight();
	}

	/**
	* Function hides search parameter div defined by id like 'paramSearchDiv_PARAM_ID'.
	* Function manages parameter select html object data
	* @param paramId       contains parameter id
	*/
	function hideSearchParam( paramId )
	{
		var paramDiv = $( 'paramSearchDiv_' + paramId );
		paramDiv.parentNode.removeChild( paramDiv );
		manageParamSelect( paramId, false );
		countProducts();
		setParamDivHeight();
	}

	/**
	* Function changes height attribute of search parameter div defined by id 'paramSearchPanelDiv'.
	*/
	function setParamDivHeight()
	{
		var paramDivHeight = 0;
		var paramDiv = $( 'paramSearchPanelDiv' );
		var oChildren = paramDiv.getElementsByTagName( 'div' );
		for( var i = 0; i < oChildren.length; i++ )
		{
			if( childName = oChildren[i].id )
			{
				if( childName.match( /^paramSearchDiv_[0-9]+$/ ) != null )
				{
					var vHeight = new Number( new String( oChildren[i].scrollHeight ).replace( /px/g, "" ) );
					//alert( paramDivHeight );
					//oChildren[i].style.top = ''+paramDivHeight+'px';
					paramDivHeight += vHeight;
				}
			}
		}
		paramDiv.style.height = ''+paramDivHeight+'px';
	}

	/**
	* Function manages html select object state that contains parameter data.
	* Id and name attribute of this object MUST be 'paramSearchSelect'
	* Document MUST contain summary div html object 'paramSearchSummaryDiv1' and 'paramSearchSummaryDiv2'
	*
	* @param paramId       string id of parameter in select
	* @param isReduced     boolean determines action on parameter describbed by id
	*                      true - parameter must be added to select object
	*                      false - parameter must be removed from select object
	*/
	function manageParamSelect( paramId, isReduced )
	{
		var paramSelect = $( 'paramSearchSelect' );
		//updating global parameters visibility
		for( var i = 0; i < PARAM_ARRAY.length; i++ )
		{
			if( PARAM_ARRAY[i].getId() == paramId )
			{
				PARAM_ARRAY[i].setVisible( !isReduced );
				break;
			}
		}
		//cleaning paramSelect
		for( var i = 0; i < paramSelect.options.length; i++ )
		{
			paramSelect.options[i] = null;
		}
		//generating paramSelect parameter options
		var optionEl = null;
		paramSelect.options[0] = new Option( EMPTY_OPTION_VALUE, '' );
		var optionCounter = 1;
		for( var i = 0; i < PARAM_ARRAY.length; i++ )
		{
			if( PARAM_ARRAY[i].isVisible() )
			{
				paramSelect.options[optionCounter] = new Option( PARAM_ARRAY[i].getName(), PARAM_ARRAY[i].getId() );
				optionCounter++;
			}
			
		}
		paramSelect.selectedIndex = 0;
		var hiddenOptionCount = 0;
		if( isReduced )
		{
			if( paramSelect.options.length == 1 )
			{
				paramSelect.style.display = 'none';
			}
			$( 'paramSearchSummaryDiv1' ).style.display = 'block';
			$( 'paramSearchSummaryDiv2' ).style.display = 'block';
		}
		else
		{
			paramSelect.style.display = 'block';
			if( paramSelect.options.length == PARAM_ARRAY.length + 1 ) 
			{
				$( 'paramSearchSummaryDiv1' ).style.display = 'none';
				$( 'paramSearchSummaryDiv2' ).style.display = 'none';
			}
		}
	}

	/**
	* Function counts products that fullfill search conditions
	* Search conditions must be defined in 'paramSearchForm' html form
	*
	* Search conditions MUST be defined as elements with name and id as:
	*
	* checkboxes - 'paramSearchParameter_PARAMETERID_VALUEID' where PARAMETERID - is parameter id and VALUEID is id of specified parameter value
	*
	* radios - 'paramSearchAllowedValues_PARAMETERID' determines if product must contain all checked values (element value 'all') or only one of them (element value 'any')
	*
	* Function sets html object values:
	* 'productNumber1' - number of products that fullfill search criteria
	* 'productNumber2' - number of products that fullfill search criteria
	* 'selectedProduct' - id of products that fillfill search criteria separated by comma
	* Those elements MUST be provided.
	*/
	function countProducts()
	{
		var form = $( 'paramSearchForm' );
		var params = new Array();
		var inputs = form.getElementsByTagName( 'input' );
		var paramMem = '';
		var parCount = 0;
		var parOrder = new Array();
		for( var i = 0; i < inputs.length; i++ )
		{
			var paramId = '';
			var valueId = '';
			//searching checked values
			if( ( inputs[i].type == 'checkbox' ) && ( inputs[i].name.match( /^paramSearchParameter_[0-9]+_[0-9]+$/ ) != null ) )
			{
				if( inputs[i].checked )
				{
					var paramString = new String( inputs[i].name ).replace( /^paramSearchParameter_/, '' );
					paramId = paramString.replace( /_[0-9]+$/, '' );
					valueId = paramString.replace( /^[0-9]+_/, '' );
					if( params[paramId] == null )
					{
						params[paramId] = new ParameterObj( paramId );
					}
					params[paramId].addValueId( valueId );
					//
					if( ( parCount == 0 ) || ( ( parCount > 0 ) && ( parOrder[parCount-1] != paramId ) ) )
					{
						parOrder[parCount] = paramId;
						parCount++;
					}
					//
				}
			}
			//searching all or any param criteria
			if( ( inputs[i].type == 'radio' ) && ( inputs[i].name.match( /^paramSearchAllowedValues_[0-9]+$/ ) != null ) )
			{
				if( inputs[i].checked )
				{
					inputs[i].focus();
					var paramId = new String( inputs[i].name ).replace( /^paramSearchAllowedValues_/, '' );
					if( params[paramId] == null )
					{
						params[paramId] = new ParameterObj( paramId );
					}
					params[paramId].useValues = inputs[i].value;
				}
			}
		}
		//
		var was = 0;
		for( i = 0; i < parCount; i++ )
		{
			if( ( typeof( params[parOrder[i]] ) == 'object' ) && ( params[parOrder[i]] != null ) )
			{
				if( was != 0 )
				{
					paramMem += ';';
				}
				paramMem += '' + params[parOrder[i]].id + '';
				for( j = 0; j < params[parOrder[i]].valueCount; j++ )
				{
					paramMem += ',' + params[parOrder[i]].valueId[j] + '';
				}
				paramMem += ',' + params[parOrder[i]].useValues + '';
				was = 1;
			}
		}
		//paramMem = '' + $( "paramSearchGroup" ).value + '.' + paramMem + '';
		$( "paramSearchMemory" ).value = paramMem;
		//alert(paramMem);
		var i,j;
		var searchInProducts = true;
		//reseting product found status
		for( i = 0; i < products.length; i++ )
		{
			products[i].resetFound();
		}
		//checking if products fillfill search criteria
		for( i = 0; i < params.length; i++ )
		{
			if( ( typeof( params[i] ) == 'object' ) && ( params[i] != null ) )
			{
				if( params[i].valueCount == 0 )
				{
					searchInProducts = false;
					break;
				}
				for( j = 0; j < products.length; j++ )
				{
					if( products[j].isFound() )
					{
						products[j].checkParam( params[i] )
					}
				}
			}
		}
		//generating selectedProduct value
		var searchCount = 0;
		var searchProductId = '';
		for( i = 0; i < products.length && searchInProducts; i++ )
		{
			if( products[i].isFound() )
			{
				searchCount++;
				searchProductId += products[i].id + ';';
			}
		}
		$( 'productNumber1' ).innerHTML = searchCount;
		$( 'productNumber2' ).innerHTML = searchCount;
		//$( 'selectedProduct' ).value = searchProductId;
		$( 'checked_product' ).value = searchProductId;
	}

	/**
	*	Opis: przesyla dane z formularza wyszukiwarki parametrycznej
	*/
	function submitParamSearchForm( formName, inputName, errorMessage )
	{
		var element = $( inputName );
		if( ( typeof( element ) == 'object' ) && ( element != null ) )
		{
			if( ( element.value != '' ) && ( element.value != '0' ) )
			{
				var form = $( formName );
				if( ( typeof( form ) == 'object' ) && ( form != null ) )
				{
					form.submit();
					return;
				}
			}
			alert( errorMessage );
		}
	}

/**-------------------------------------------------------------------*/


