<?php

	class kBracketsHelper extends kHelper {
		
		/**
		 * Field name holding minimal amount
		 *
		 * @var string
		 */
		var $min_field = '';
		
		/**
		 * Field name holding maximal amount
		 *
		 * @var string
		 */
		var $max_field = '';	

		/**
		 * Default values to be set to automtically created price brackets
		 *
		 * @var Array
		 */
		var $default_values = Array();
		
		function InitHelper($min_field, $max_field, $default_values)
		{
			$this->min_field = $min_field;
			$this->max_field = $max_field;
			$this->default_values = $default_values;
		}
		
		
		/**
		 * Adds 5 more empty brackets to brackets
		 *
		 * @param kEvent $event
		 */
		function OnMoreBrackets(&$event)
		{
			$field_values = $this->Application->GetVar( $event->getPrefixSpecial(true) );
			
			$object =& $event->getObject();

			foreach($field_values as $id => $record)
			{
				if($record[$this->max_field] == '&#8734;') $field_values[$id][$this->max_field] = -1;
			}

			$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$object->IDField.') FROM '.$object->TableName);
			if($new_id > 0) $new_id = 0;
			do
			{
				$new_id--;
			}while( $this->arraySearch($field_values, $object->IDField, $new_id) );


			$last_max_qty = $this->Conn->GetOne('SELECT MAX('.$this->max_field.') FROM '.$object->TableName);
			$min_qty = $this->Conn->GetOne('SELECT MIN('.$this->max_field.') FROM '.$object->TableName);

			if($min_qty == -1) $last_max_qty = -1;
			if(!$last_max_qty) $last_max_qty = 1;


			for($i = $new_id; $i > $new_id - 5; $i--)
			{
				$field_values[$i][$object->IDField] = $i;
				$field_values[$i][$this->min_field] = ($i == $new_id-4 && $last_max_qty != -1) ? $last_max_qty : '';
				$field_values[$i][$this->max_field] = ($i == $new_id-4 && $last_max_qty != -1) ? -1 : '';
				$field_values[$i] = array_merge_recursive2($field_values[$i], $this->default_values);
			}

			$event->CallSubEvent('OnPreSaveBrackets');

			$this->Application->SetVar($event->getPrefixSpecial(true), $field_values);
		}
		
		/**
		 * Adds infinity bracket
		 *
		 * @param kEvent $event
		 */
		function OnInfinity(&$event)
		{
			$object =& $event->getObject();
			$infinite_exists = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$object->TableName.' WHERE '.$this->max_field.' = -1');

			if($infinite_exists == 0)
			{
				$field_values = $this->Application->GetVar( $event->getPrefixSpecial(true) );
				
				reset($field_values);
				$last_bracket = end($field_values);
				$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$object->IDField.') FROM '.$object->TableName);

				$brackets_exist = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.$object->TableName);

				if($new_id > 0) $new_id = 0;
				do
				{
					$new_id--;
				}while( $this->arraySearch($field_values, $object->IDField, $new_id) );

				$infinite_bracket[$object->IDField] = $new_id;
				$infinite_bracket[$this->min_field] = ($brackets_exist > 0) ? $last_bracket[$this->max_field] : 1;
				$infinite_bracket[$this->max_field] = '-1';
				$infinite_bracket = array_merge_recursive2($infinite_bracket, $this->default_values);
				
				$field_values[$new_id] = $infinite_bracket;
				reset($field_values);
				
				$this->Application->SetVar($event->getPrefixSpecial(true), $field_values);
			}
		}
		
		/**
		 * Saves brackets to database
		 *
		 * @param kEvent $event
		 */
		function OnPreSaveBrackets(&$event)
		{
			$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true));
			if($items_info)
			{
				$object =& $event->getObject();

				$linked_info = $object->getLinkedInfo();
				$stored_ids = $this->Conn->GetCol('SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE '.$linked_info['ParentTableKey'].' = '.$linked_info['ParentId']);
				
				uasort($items_info, Array(&$this, 'compareBrackets') );

				foreach ($items_info as $item_id => $values)
				{

					if (in_array($item_id, $stored_ids)) { //if it's already exist
					$object->SetDefaultValues();
					$object->Load($item_id);
					$object->SetFieldsFromHash($values);
					if (!$object->Validate()) {
						unset($stored_ids[array_search($item_id, $stored_ids)]);
						$event->redirect = false;
						continue;
					}
					if( $object->Update($item_id) )
					{
						$event->status = erSUCCESS;
					}
					else
					{
						$event->status = erFAIL;
						$event->redirect = false;
						break;
					}
					unset( $stored_ids[ array_search($item_id, $stored_ids) ] );
					}
					else {
						$object->SetDefaultValues();
						$object->SetFieldsFromHash($values);
						$object->SetDBField($linked_info['ParentTableKey'], $linked_info['ParentId']);

						if( $object->Create() )
						{
							$object->setTempID();
							$event->status = erSUCCESS;
						}
					}
				}

				// delete
				foreach ($stored_ids as $stored_id){
					$this->Conn->Query('DELETE FROM '.$object->TableName.' WHERE '.$object->IDField.' = '.$stored_id);
				}

			}
		}
		
		function arrangeBrackets(&$event)
		{
			$object =& $event->getObject();
			
			$temp = $this->Application->GetVar( $event->getPrefixSpecial(true) );
			
			foreach($temp as $id => $record)
			{
				if( $record[$this->max_field] == '&#8734;' )
				{
					$temp[$id][$this->max_field] = -1;
				}
			}
			
			$temp_orig = $temp;
			reset($temp);
			if( is_array($temp) )
			{
				// array to store max values (2nd column)
				$end_values = Array();

				// get minimal value of Min
				$first_elem = current($temp);
				$start = $first_elem[$this->min_field];
				if(!$start) $start = 1;
				
				foreach($temp as $id => $record)
				{
					if(
					// MAX is less than start
					($record[$this->max_field] <= $start && $record[$this->max_field] != -1) ||
					// Max is empty
					!$record[$this->max_field] ||
					// Max already defined in $end_values
					(array_search($record[$this->max_field], $end_values) !== false)
					) {	// then delete from brackets list
					unset($temp[$id]);
					}
					else {	// this is when ok - add to end_values list
					$end_values[] = $record[$this->max_field];
					}
				}

				// sort brackets by 2nd column (Max values)
				uasort($temp, Array(&$this, 'compareBrackets') );
				reset($temp);
				$first_item = each($temp);
				$first_item_key = $first_item['key'];

				$linked_info = $object->getLinkedInfo();
				$sql = 'SELECT %s FROM %s WHERE %s = %s';
				$ids = $this->Conn->GetCol( sprintf($sql, $object->IDField, $object->TableName, $linked_info['ParentTableKey'], $linked_info['ParentId']) );
				if( is_array($ids) )
				{
					usort($ids, Array(&$this, 'sortBracketIDs') );
				}
				
				$min_id = min( min($ids) - 1, -1 );

				foreach($temp as $key => $record)
				{
					$temp[$key][$this->min_field] = $start;
					$start = $temp[$key][$this->max_field];
				}
			}
			
			$this->Application->SetVar($event->getPrefixSpecial(true), $temp);
			return $temp;
		}
		
		function compareBrackets($bracket1, $bracket2) // ap_bracket_comp
		{
			$bracket1_min = $bracket1[$this->min_field];
			$bracket1_max = $bracket1[$this->max_field];
			
			$bracket2_min = $bracket2[$this->min_field];
			$bracket2_max = $bracket2[$this->max_field];
			
			// limits
			if( ($bracket1_min != '') && ($bracket1_max == '') && ($bracket2_min != '') && ($bracket2_max != '') ) return 1;
			if( ($bracket1_min != '') && ($bracket1_max == '') && ($bracket2_min == '') && ($bracket2_max == '') ) return -1;
			if( ($bracket1_max == '') && ($bracket2_max != '') ) return 1;
			if( ($bracket1_max != '') && ($bracket2_max == '') ) return -1;


			if( ( ($bracket1_max > $bracket2_max) && ($bracket2_max != -1) ) || ( ($bracket1_max == -1) && ($bracket2_max != -1) ) )
			{
				return 1;
			}
			elseif( ($bracket1_max < $bracket2_max) || ( ($bracket2_max == -1) && ($bracket1_max != -1) ) )
			{
				return -1;
			}
			else
			{
				return 0;
			}
		}
		
		function sortBracketIDs($first_id, $second_id) // pr_bracket_id_sort
		{
			$first_abs = abs($first_id);
			$second_abs = abs($second_id);
			
			$first_sign = ($first_id == 0) ? 0 : $first_id / $first_abs;
			$second_sign = ($second_id == 0) ? 0 : $second_id / $second_abs;
			
			if($first_sign != $second_sign)
			{
				if($first_id > $second_id)
				{
					$bigger =& $first_abs;
					$smaller =& $second_abs;
				}
				else
				{
					$bigger =& $second_abs;
					$smaller =& $first_abs;
				}
				$smaller = $bigger + $smaller;
			}

			return ($first_abs > $second_abs) ? 1 : ($first_abs < $second_abs ? -1 : 0);
		}
		
		/**
		 * Searches through submitted grid data to find record with specific value in specific field
		 *
		 * @param Array $records // grid data from REQUEST
		 * @param string $field
		 * @param string $value
		 * @return bool
		 */
		function arraySearch($records, $field, $value) // check_array
		{
			foreach ($records as $record)
			{
				if ($record[$field] == $value)
				{
					return true;
				}
			}
			return false;
		}
		
		/**
		 * Replate infinity mark with -1 before saving to db
		 *
		 * @param kEvent $event
		 */
		function replaceInfinity(&$event)
		{
			$object =& $event->getObject();
			if($object->GetDBField($this->max_field) == '&#8734;') $bracket->SetDBField($this->max_field, -1);
		}
		
	}

?>