<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class looks after ADSL products
 *
 * @package    ADSL
 * @category   Product
 * @author     Deon George
 * @copyright  (c) 2009-2013 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class ADSL {
	// Map the table fields
	static $map = array(
		'base_up_offpeak'=>'extra_up_offpeak',
		'base_down_offpeak'=>'extra_down_offpeak',
		'base_up_peak'=>'extra_up_peak',
		'base_down_peak'=>'extra_down_peak',
	);

	/**
	 * Return an instance of this class
	 *
	 * @return ADSL
	 */
	public static function instance() {
		return new ADSL;
	}

	public function contract_view($data,$price_base,$price_setup) {
		// @todo - this test shouldnt be required
		if (preg_match('/^a:/',$data))
			throw new Kohana_Exception('Data shouldnt be a serialized array');

		$ao = ORM::factory('ADSL_Plan',$data);
		$output = View::factory('adsl/contract_view')
			->set('record',$ao)
			->set('price_base',$price_base)
			->set('price_setup',$price_setup);

		return $output;
	}

	/**
	 * Collect information for the cart
	 */
	public function product_cart() {
	}

	/**
	 * Map the metric fields to their excess rate
	 */
	public static function map($metric) {
		return ADSL::$map[$metric];
	}

	/**
	 * Calculate the allowance array or traffic used array
	 *
	 * If:
	 *   + UPLOADS are charged and there are no PEAK/OFFPEAK periods (therefore all
	 *     traffic is charged), the allowance will be shown as 1 metric - TRAFFIC.
	 *   + UPLOADS are charged and there are PEAK/OFFPEAK periods the allowance
	 *     will be shown as 2 metrics - PEAK/OFFPEAK.
	 *   + UPLOADS are NOT charged and there are no PEAK/OFFPEAK periods the allowance
	 *     will be shown as 1 metrics - TRAFFIC.
	 *   + UPLOADS are NOT charged and there are PEAK/OFFPEAK periods the allowance
	 *     will be shown as 2 metrics - PEAK/OFFPEAK.
	 *
	 * Thus:
	 *   + If base_x_Y is NULL, all Y traffic is FREE (ignore respective extra_x_Y setting).
	 *   + If base_x_Y is a number, all Y traffic is FREE up to the number (evaluate extra_x_Y setting).
	 *   + If extra_x_Y is a number, charge this amount for traffic over base_x_Y.
	 *   + If extra_down_peak is NULL this is invalid, treat base_down_peak as NULL
	 *   + If extra_down_offpeak is NULL add traffic_down_offpeak to traffic_down_peak
	 *   + If extra_up_peak is NULL add traffic_up_peak to traffic_down_peak
	 *   + If extra_up_offpeak is NULL add traffic_up_offpeak to traffic_down_offpeak
	 *
	 * @param array $plan - the allowance plan
	 */
	public static function allowance($plan) {
		// Map the NULL relationships
		$extras = array(
			'extra_up_offpeak'=>'base_down_offpeak',
			'extra_down_offpeak'=>'base_down_peak',
			'extra_up_peak'=>'base_down_peak',
			'extra_down_peak'=>'base_down_peak',
		);

		// Work out if we charge each period
		$a = array();
		if (! isset($plan['extra_down_peak']) OR is_null($plan['extra_down_peak']))
			$a['base_down_peak'] = 0;

		foreach (ADSL::$map as $k => $v) {
			// Work through attributes we count.
			if (isset($plan[$k]) AND ! is_null($plan[$k])) {

				// Work through attributes that are merged
				if (! isset($plan[$v]) OR is_null($plan[$v])) {

					if (isset($a[$k])) {
						if (isset($a[$extras[$v]]))
							$a[$extras[$v]] += $a[$k];
						else
							$a[$extras[$v]] = $a[$k];

						unset($a[$k]);
					}

					if (isset($a[$extras[$v]]))
						$a[$extras[$v]] += $plan[$k];
					else
						$a[$extras[$v]] = $plan[$k];

				} else {
						if (isset($a[$k]))
							$a[$k] += $plan[$k];
						else
							$a[$k] = $plan[$k];
				}
			}
		}

		// Return the output sorted
		$result = array();
		foreach (array('base_down_peak','base_down_offpeak','base_up_peak','base_up_offpeak') as $k)
			if (isset($a[$k]))
				$result[$k] = $a[$k];

		return $result;
	}
}
?>