<?php if (!defined('HTTP_SERVER')) die('You can not access this file directly!');
/**
  \licence GPL 2005-2010  The osCSS developers - osCSS Open Source E-commerce
  \portion code Copyright (c) 2002 osCommerce
  \package osCSS-2 <www http://www.oscss.org>
  \version 2.1.0
  \date  29/11/10, 11:33
  \author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  \encode UTF-8
  \class shipping
  \file 
  \dir includes/classes/
  
  \brief class de d'appel et execution des modules de livraison
*/

class shipping
  extends AbstractAcaModule{
  var $modules;

  /**
    @p int nombre colis
  */
  public static $shipping_num_boxes = 1;

  protected static $_instance;

  function __construct($module='') {
    self::initialise($module);
  }

  public static function getInstance($module='') {
      if(self::$_instance == null) {
	  self::$_instance = new self($module);
      }
      return self::$_instance;
  }

  public static function resetInstance() {
      self::$_instance = null;
      return self::getInstance();
  }

  /**
   * \fn initialise($module = '')
   * \brief class constructor
    @param $module string/empty le nom du module, passé apres choix
  */
  private function initialise($module = '') {
    global $language, $customer_id,$PHP_SELF, $page ,$lang;

    $include_modules = array();
    if (tep_not_null($module) && is_array($module)) {
      $mod=substr($module["id"], strpos($module["id"],'_')+1);
      $this->selected_module = $module;
      if(($path=$page->fix_file(DIR_WS_INCLUDES .'languages/'. $language . '/modules/shipment/' . $mod . '.php',true)) !=false) require($path);
      if(($path=$page->fix_file(DIR_WS_MODULES . 'shipment/' . $mod . '.php')) !=false) require($path);
      $include_modules[] = array_merge($module, array('class' =>$mod) );
    } else {
      foreach(parent::initialise_type('MODULE_SHIPPING_INSTALLED','shipping') as $class){
	$include_modules[] = array('class' => $class, 'file' => $class . '.php');
      }
    }

    if (isset($_SESSION['sppc_customer_group_id']) && $_SESSION['sppc_customer_group_id'] != '0') $customer_group_id = $_SESSION['sppc_customer_group_id'];
    else  $customer_group_id = '0';

    $customer_shipment_query = tep_db_query("select IF(c.customers_shipment_allowed <> '', c.customers_shipment_allowed, cg.group_shipment_allowed) as shipment_allowed from " . TABLE_CUSTOMERS . " c, " . TABLE_CUSTOMERS_GROUPS . " cg where c.customers_id = '" . $customer_id . "' and cg.customers_group_id =  '" . $customer_group_id . "'");
    $customer_ot = tep_db_fetch_array($customer_shipment_query);
    $temp_ot_array= (tep_not_null($customer_ot['shipment_allowed']) )  ? explode(';', $customer_ot['shipment_allowed']) : array() ;

    foreach($include_modules as $imod){
      if( ( count($temp_ot_array)==0 || in_array($imod['file'], $temp_ot_array ) ) ){
	if(!empty($imod['class']) && !class_exists($imod['class'])) break;
	$this->modules[$imod['class']]=$GLOBALS[$imod['class']] = new $imod['class'];
      }
    }
  }

  /**
   * \fn quote($method = '', $module = '')
   * @param $method
   * @param $module
   */
  public function quote($method = '', $module = '') {
    global $total_weight, $shipping_weight, $shipping_quoted/*, $shipping_num_boxes*/;

    $quotes_array = array();

    if (is_array($this->modules)) {
      $shipping_quoted = '';
//       self::$shipping_num_boxes = 1;
      $shipping_weight = $total_weight;

      if (SHIPPING_BOX_WEIGHT >= $shipping_weight*SHIPPING_BOX_PADDING/100) {
	$shipping_weight = $shipping_weight+SHIPPING_BOX_WEIGHT;
      } else {
	$shipping_weight = $shipping_weight + ($shipping_weight*SHIPPING_BOX_PADDING/100);
      }

      if ($shipping_weight > SHIPPING_MAX_WEIGHT) { // Split into many boxes
	self::$shipping_num_boxes = ceil($shipping_weight/SHIPPING_MAX_WEIGHT);
	$shipping_weight = $shipping_weight/self::$shipping_num_boxes;
      }

      $include_quotes = array();

      reset($this->modules);

      foreach($this->modules as $class=>$s){
	if (tep_not_null($module)) {
	  if ( ($module == $class) && ($GLOBALS[$class]->enabled) ) $include_quotes[] = $class;
	}
	elseif ($GLOBALS[$class]->enabled)  $include_quotes[] = $class;
      }

      $size = sizeof($include_quotes);
      for ($i=0; $i<$size; $i++) {
	$quotes = $GLOBALS[$include_quotes[$i]]->quote($method);
	if (is_array($quotes)) $quotes_array[] = $quotes;
      }
    }

    return $quotes_array;
  }

  /**
   * \fn cheapest()
    \brief Meilleur methode (la moins chere)
  */
  public function cheapest() {
    if (is_array($this->modules)) {
      $rates = array();

      reset($this->modules);
      foreach($this->modules as $class=>$s){
	if ($GLOBALS[$class]->enabled && (($quotes = $GLOBALS[$class]->quotes) !=false) ) {
	  for ($i=0, $n=sizeof($quotes['methods']); $i<$n; $i++) {
	    if (isset($quotes['methods'][$i]['cost']) && tep_not_null($quotes['methods'][$i]['cost'])) {
	      $rates[] = array('id' => $quotes['id'] . '_' . $quotes['methods'][$i]['id'],
				'title' => $quotes['module'] . ' (' . $quotes['methods'][$i]['title'] . ')',
				'cost_ht' => @$quotes['methods'][$i]['cost_ht'],
				'cost' => $quotes['methods'][$i]['cost']);
	    }
	  }
	}
      }

      $cheapest = false;
      for ($i=0, $n=sizeof($rates); $i<$n; $i++) {
	if (is_array($cheapest)) {
	  if ($rates[$i]['cost'] < $cheapest['cost']) {
	    $cheapest = $rates[$i];
	  }
	} else {
	  $cheapest = $rates[$i];
	}
      }

      return $cheapest;
    }
  }

  /**
   * \fn getGeoZoneID($country_id, $zone_id) 
    \brief Necessaire dans les module enfants
    Control $zone_id && $country_id. Si false module desactivé
    @param $country_id \a int  de customers venant de order
    @param $zone_id \a int  de customers venant de order
  */
  public static function getGeoZoneID($country_id, $zone_id) {
    $cache=array();
    static $cache;

    $key = 'country_'.(int)$country_id.'zone_'.(int)$zone_id;
    if(isset($cache[$key])) return $cache[$key];

    $DB=Database::getInstance();
    // First, check for a Geo Zone that explicity includes the country & specific zone (useful for splitting countries with zones up)
    $zone_query = $DB->query("select gz.geo_zone_id from " . TABLE_GEO_ZONES . " gz left join " . TABLE_ZONES_TO_GEO_ZONES . " ztgz on (gz.geo_zone_id = ztgz.geo_zone_id) where ztgz.zone_country_id = '" . (int)$country_id . "' and ztgz.zone_id = '" . (int)$zone_id . "' and LOWER(gz.geo_zone_name) like 'shp%'");

    if ($zone_query->__get('numRows')) {
      $zone = $zone_query->fetchAssoc();
      return $cache[$key]=$zone['geo_zone_id'];
    } else {
      // No luck…  Now check for a Geo Zone for the country and "All Zones" of the country.
      $zone_query = $DB->query("select gz.geo_zone_id from " . TABLE_GEO_ZONES . " gz left join " . TABLE_ZONES_TO_GEO_ZONES . " ztgz on (gz.geo_zone_id = ztgz.geo_zone_id) where ztgz.zone_country_id = '" . (int)$country_id . "' and (ztgz.zone_id = '0' or ztgz.zone_id is NULL) and LOWER(gz.geo_zone_name) like 'shp%'");

      if ($zone_query->__get('numRows')) {
	$zone = $zone_query->fetchAssoc();
	return $cache[$key]=$zone['geo_zone_id'];
      }
    }
    return $cache[$key]=false;
  }

  /**
   * \fn get_icon($path, $title) 
   * \brief display icon if exist 
   * @param $path
   * @param $title
   */
  public static function get_icon($path, $title) {
    return tep_image( (strpos($path,DIR_WS_CATALOG) ==false )
			? substr(str_replace('//','/',$path), strlen(DIR_WS_CATALOG) )
			:  $path,
		      $title);
  }

}
?>