<?php
/*
  French Colissimo Shipping module version 20120301.
  This module has been adapted to fit in OpenCart 1.5.x.

  @package shippingMethod
  @copyright Copyright © 2011,2012 Philippe BLAIN <pblain@NOSPAMfree.fr>.

  ------------------------------------------------------------------------------
  RAPPELS :

  DOM : Guadeloupe(971),  Martinique(972), Guyanne Française(973), Réunion(974).
  TOM : Nouvelle Calédonie(988), Polynésie française(987), Wallis & Futuna(986),
        Îles éparses de l'Océan Indien + Terres Australes et Arctiques françaises(984).
  Collectivités Territoriales : Saint-Pierre & Miquelon(975), Mayotte(976),
        Saint-Barthélemy(977), Saint-Martin(978).

  ------------------------------------------------------------------------------
*/
class ModelShippingColissimo extends Model {

  /* Symboles indépendants de la langue */
  const MODULE_SHIPPING_COLISSIMO_MARK_UNITS       = ' Kgs ';
  const MODULE_SHIPPING_COLISSIMO_MARK_AD_VALOREM  = ' +ADV';
  const MODULE_SHIPPING_COLISSIMO_MARK_CRBT        = ' +CRBT';
  const MODULE_SHIPPING_COLISSIMO_MARK_AR          = ' +AR';
  const MODULE_SHIPPING_COLISSIMO_MARK_ECO         = ' -ECO';
  const MODULE_SHIPPING_COLISSIMO_MARK_INTERNET    = ' -WEB';

  /***********************************************************************
  **  TARIFS PUBLICS COLISSIMO AU 1er MARS 2012, EN EUROS NETS ET KG.
  **  Toutes les modifications tarifaires doivent être faites ici, en dur.
  ***********************************************************************/
  /* Poids maximum expédiable par défaut: 30 Kg */
  const MODULE_SHIPPING_COLISSIMO_MAX_POIDS = 30;

  /* Suppléments pour recommandés */
  const MODULE_SHIPPING_COLISSIMO_SUPP_R1 = 2.5;
  const MODULE_SHIPPING_COLISSIMO_SUPP_R2 = 3.4;
  const MODULE_SHIPPING_COLISSIMO_SUPP_R3 = 4.6;
  const MODULE_SHIPPING_COLISSIMO_SUPP_R4 = 5.8;
  const MODULE_SHIPPING_COLISSIMO_SUPP_R5 = 7;

  /* Montant maximum CRBT par défaut: 1500 EUR */
  const MODULE_SHIPPING_COLISSIMO_MAX_CRBT = 1500;

  /* Options */
  const MODULE_SHIPPING_COLISSIMO_SUPP_AVIS_RECEPTION = 1.3;
  const MODULE_SHIPPING_COLISSIMO_SUPP_AD_VALOREM = 1;
  const MODULE_SHIPPING_COLISSIMO_TRANCHE_AD_VALOREM = 150;
  const MODULE_SHIPPING_COLISSIMO_MAX_AD_VALOREM = 1500;

  /* Pourcentage de réduction pour affranchissement en ligne */
  const MODULE_SHIPPING_COLISSIMO_INTERNET_PERCENT = 5;

  protected $offre = array (
    /* 0 - Tarifs au départ de France métropolitaine à destination de France métropolitaine, Andorre, Monaco et le Secteur Postal 69000,
       à l'intérieur des DOM et pour les relations réciproques Guadeloupe et Martinique */
    array (
      'code' => 'national',
      'crbt' => 7,
      'tarifs' => array (
        'normal' => '0.5:6.50,1:6.90,2:8.50,3:9.50,5:11.35,7:13.35,10:16.35,15:18.85,30:26.35',
      ),
      'delais' => array (
        'normal' => 2,
      ),
    ),
    /* 1 - Tarifs au départ de France métropolitaine à destination des DOM, Mayotte, Saint-Pierre et Miquelon,
       OU au départ des DOM, Mayotte, Saint Pierre et Miquelon à destination de France métropolitaine, Monaco et Andorre */
    array (
      'code' => 'dom',
      'crbt' => 7,
      'tarifs' => array (
        'normal' => '0.5:8.60,1:12.9,2:17.35,3:22,4:26.65,5:31.3,6:35.95,7:40.6,8:45.25,9:49.9,10:54.55,15:77.75,20:100.95,25:124.15,30:147.35',
        'econom' => '0.5:7.6,1:9.7,2:11.3,3:12.9,4:14.5,5:16.1,6:17.7,7:19.3,8:20.9,9:22.5,10:24.1,15:32.1,20:40.1,25:48.1,30:56.1',
      ),
      'delais' => array (
        'normal' => array(5, 7),
        'econom' => array(18, 27),
      ),
    ),
    /* 2 - Tarifs pour les envois entre DOM de proximité (y compris Mayotte)
       Guadeloupe <---> Guyane / Martinique <---> Guyane / Réunion <---> Mayotte */
    array (
      'code' => 'dom_proxi',
      'crbt' => 7,
      'tarifs' => array (
        'normal' => '0.5:5.65,1:6.8,2:7.95,3:9.1,4:10.25,5:11.4,6:12.55,7:13.7,8:14.85,9:16,10:17.15,15:19.15,20:21.15,25:23.15,30:25.15',
      ),
      'delais' => array (
        'normal' => array(3, 5),
      ),
    ),
    /* 3 - Tarifs pour les envois entre DOM éloignés (y compris Mayotte)
       Guadeloupe, Martinique, Guyane avec Réunion et Mayotte.
       Guadeloupe, Martinique, Guyane, Réunion et Mayotte vers Saint Pierre et Miquelon. */
    array (
      'code' => 'dom_eloigne',
      'crbt' => 7,
      'tarifs' => array (
        'normal' => '0.5:9.95,1:15.45,2:27.9,3:40.35,4:52.8,5:65.25,6:77.7,7:90.15,8:102.6,9:115.05,10:127.5,15:188.5,20:249.5,25:310.5,30:371.5',
        'econom' => '0.5:8.6,1:10.1,2:11.85,3:13.6,4:15.35,5:17.1,6:18.85,7:20.6,8:22.35,9:24.1,10:25.85,15:34.6,20:43.35,25:52.1,30:60.85',
      ),
      'delais' => array (
        'normal' => array(10, 14),
        'econom' => array(35, 45),
      ),
    ),
    /* 4 - Tarifs au départ de France métropolitaine vers les TOM,
       OU au départ des DOM, Collectivités Territoriales vers les TOM */
    array (
      'code' => 'tom',
      'crbt' => 7,
      'tarifs' => array (
        'normal' => '0.5:10.1,1:15.2,2:26.8,3:38.4,4:50,5:61.6,6:73.2,7:84.8,8:96.4,9:108,10:119.6,15:177.6,20:235.6,25:293.6,30:351.6',
        'econom' => '0.5:9.95,1:12.95,2:22.55,3:32.15,4:41.75,5:51.35,6:60.95,7:70.55,8:80.15,9:89.75,10:99.35,15:147.35,20:195.35,25:243.35,30:291.35',
      ),
      'delais' => array (
        'normal' => array(10, 14),
        'econom' => array(18, 27),
      ),
    ),
    /* 5 - Tarifs depuis Métropole vers l'International */
    array (
      'code' => 'inter',
      'crbt' => 8,
      'tarifs' => array (
        /* Tarifs au départ de France métropolitaine vers l'International (zones A, B, C et D)*/
        'normal_1' => '1:16.15,2:17.85,3:21.55,4:25.25,5:28.95,6:32.65,7:36.35,8:40.05,9:43.75,10:47.45,15:54.65,20:61.85,25:69.05,30:76.25',
        'normal_2' => '1:19.8,2:21.7,3:26.25,4:30.8,5:35.35,6:39.9,7:44.45,8:49,9:53.55,10:58.1,15:68.5,20:78.9',
        'normal_3' => '1:23.2,2:31.1,3:40.9,4:50.7,5:60.5,6:70.3,7:80.1,8:89.9,9:99.7,10:109.5,15:133.6,20:157.7,',
        'normal_4' => '1:26.4,2:39.7,3:52.9,4:66.1,5:79.3,6:92.5,7:105.7,8:118.9,9:132.1,10:145.3,15:171.3,20:197.3',
      ),
      'delais' => array (
        'normal_1' => array(4, 8),
        'normal_2' => array(4, 8),
        'normal_3' => array(4, 8),
        'normal_4' => array(4, 8),
      ),
    ),
    /* 6 - Tarifs depuis DOM vers l'International */
    array (
      'code' => 'dom_inter',
      'crbt' => 8,
      'tarifs' => array (
         /* Tarifs au départ des DOM et Mayotte, Saint-Pierre et Miquelon vers l'International (zones A et B) */
        'normal_1' => '1:13.7,2:17.9,3:22.1,4:26.3,5:30.5,6:34.7,7:38.9,8:43.1,9:47.3,10:51.5,15:61.9,20:72.3',
        'normal_2' => '1:28.15,2:36.8,3:45.45,4:54.1,5:62.75,6:71.4,7:80.05,8:88.7,9:97.35,10:106,15:148.8,20:191.6,25:234.4,30:277.2',
      ),
      'delais' => array (
        'normal_1' => array(5, 14),
        'normal_2' => array(5, 14),
      ),
    ),
  );
  /***********************************************************************
  **  FIN TARIFS COLISSIMO
  ***********************************************************************/

  /* Table[origine][destination] donnant l'indice dans le tableau "offre"
     au départ de Métropole, DOM-TOM vers Métropole, DOM-TOM, Andorre et Monaco
     Ici, vous pouvez désactiver finement vos expéditions en mettant -1 dans une destination non-désirée */
  protected $zone_france_et_domtom = array (
    /* France */
    'FR' =>  array('FR'=> 0,'FX'=> 0,'MC'=> 0,'AD'=> 0,'GP'=> 1,'MQ'=> 1,'BL'=> 1,'MF'=> 1,'GF'=> 1,'RE'=> 1,'YT'=> 1,'PM'=> 1,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'FX' =>  array('FR'=> 0,'FX'=> 0,'MC'=> 0,'AD'=> 0,'GP'=> 1,'MQ'=> 1,'BL'=> 1,'MF'=> 1,'GF'=> 1,'RE'=> 1,'YT'=> 1,'PM'=> 1,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    /* DOM */
    'GP' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 0,'MQ'=> 0,'BL'=> 0,'MF'=> 0,'GF'=> 2,'RE'=> 3,'YT'=> 3,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'MQ' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 0,'MQ'=> 0,'BL'=> 0,'MF'=> 0,'GF'=> 2,'RE'=> 3,'YT'=> 3,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'BL' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 0,'MQ'=> 0,'BL'=> 0,'MF'=> 0,'GF'=> 2,'RE'=> 3,'YT'=> 3,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'MF' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 0,'MQ'=> 0,'BL'=> 0,'MF'=> 0,'GF'=> 2,'RE'=> 3,'YT'=> 3,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'GF' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 2,'MQ'=> 2,'BL'=> 2,'MF'=> 2,'GF'=> 0,'RE'=> 3,'YT'=> 3,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'RE' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 3,'MQ'=> 3,'BL'=> 3,'MF'=> 3,'GF'=> 3,'RE'=> 0,'YT'=> 2,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'YT' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 3,'MQ'=> 3,'BL'=> 3,'MF'=> 3,'GF'=> 3,'RE'=> 2,'YT'=> 0,'PM'=> 3,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    'PM' =>  array('FR'=> 1,'FX'=> 1,'MC'=> 1,'AD'=> 1,'GP'=> 3,'MQ'=> 3,'BL'=> 3,'MF'=> 3,'GF'=> 3,'RE'=> 3,'YT'=> 3,'PM'=> 0,'TF'=> 4,'WF'=> 4,'PF'=> 4,'NC'=> 4,'CP'=> 4),
    /* TOM */
    'TF' =>  array('FR'=> 4,'FX'=> 4,'MC'=> 4,'AD'=> 4,'GP'=> 4,'MQ'=> 4,'BL'=> 4,'MF'=> 4,'GF'=> 4,'RE'=> 4,'YT'=> 4,'PM'=> 4,'TF'=> 0,'WF'=>-1,'PF'=>-1,'NC'=>-1,'CP'=>-1),
    'WF' =>  array('FR'=> 4,'FX'=> 4,'MC'=> 4,'AD'=> 4,'GP'=> 4,'MQ'=> 4,'BL'=> 4,'MF'=> 4,'GF'=> 4,'RE'=> 4,'YT'=> 4,'PM'=> 4,'TF'=>-1,'WF'=> 0,'PF'=>-1,'NC'=>-1,'CP'=>-1),
    'PF' =>  array('FR'=> 4,'FX'=> 4,'MC'=> 4,'AD'=> 4,'GP'=> 4,'MQ'=> 4,'BL'=> 4,'MF'=> 4,'GF'=> 4,'RE'=> 4,'YT'=> 4,'PM'=> 4,'TF'=>-1,'WF'=>-1,'PF'=> 0,'NC'=>-1,'CP'=>-1),
    'NC' =>  array('FR'=> 4,'FX'=> 4,'MC'=> 4,'AD'=> 4,'GP'=> 4,'MQ'=> 4,'BL'=> 4,'MF'=> 4,'GF'=> 4,'RE'=> 4,'YT'=> 4,'PM'=> 4,'TF'=>-1,'WF'=>-1,'PF'=>-1,'NC'=> 0,'CP'=>-1),
    'CP' =>  array('FR'=> 4,'FX'=> 4,'MC'=> 4,'AD'=> 4,'GP'=> 4,'MQ'=> 4,'BL'=> 4,'MF'=> 4,'GF'=> 4,'RE'=> 4,'YT'=> 4,'PM'=> 4,'TF'=>-1,'WF'=>-1,'PF'=>-1,'NC'=>-1,'CP'=> 0), /* TOM: Clipperton */
  );

  /* Union Européenne (27 pays - modifiable selon vos restrictions). Les pays et territoires d'outre-mer ne font pas partie de l'UE. */
  protected $zone_union_europeenne = array ('AT','BE','BG','CY','CZ','DE','DK','EE','ES','FI','FR','GB','GR','HU','IE','IT','LT','LU','LV','MT','NL','PL','PT','RO','SE','SI','SK');

  /*
    --- ZONES INTERNATIONALES COLISSIMO ---

    1°) DEPUIS ['FR' France, 'FX' Métropole]:
    Pays en zone A:
    Açores, Allemagne, Autriche, Belgique, Chypre, Danemark, Espagne, Estonie, Finlande, Gibraltar, Grande-Bretagne, Gernesey, Grèce,
    Hongrie, Irlande, Italie, Jersey, Lettonie, Lituanie, Liechtenstein, Luxembourg, Madère, Malte, Pays-Bas, Pologne, Portugal,
    Slovaquie, Slovénie, Saint-Marin, Suède, Suisse, Tchèque (Rép.), Vatican.

    Pays en zone B:
    Algérie, Albanie, Arménie, Azerbaïdjan, Belarus, Bosnie-Herzégovine, Bulgarie, Croatie, Géorgie, Islande, Macédoine, Roumanie,
    Russie (Fédération de), Serbie et Monténégro, Turquie, Ukraine, Maroc, Moldova, Norvège, Tunisie.

    Pays en zone C:
    Afrique du Sud, Angola, Arabie Saoudite (Royaume), Bahraïn, Bénin, Botswana, Burkina Faso, Burundi, Cameroun, Canada,
    Cap-Vert, Centrafrique, Comores, Congo (Rép. du), Congo (Rép. Dém. du ex-Zaïre), Côte d’Ivoire (Rép. de la), Djibouti, Egypte,
    Emirats Arabes Unis, Erythrée, Etats Unis, Ethiopie, Gabon, Gambie, Ghana,Guinée (Rép. de), Guinée-Bissau, Guinée Equatoriale,
    Iran, Iraq, Israël, Jordanie, Kenya, Lesotho, Liban, Libéria, Libye (Jamahiriya Libyenne), Madagascar, Malawi, Mali, Maurice,
    Mauritanie, Mozambique, Namibie, Niger, Nigéria, Ouganda, Porto-Rico, Qatar, Rwanda, Seychelles, Sao Tome et Principe, Sénégal,
    Sierra Leone, Somalie, Soudan, Swaziland,  Syrie (Rép. Arabe Syrienne), Tanzanie, Tchad, Togo, Yémen, Zambie, Zimbabwe.

    Pays en zone D:
    Afghanistan, Anguilla, Antigua & Barbuda, Argentine, Aruba, Australie, Bahamas, Bangladesh, Barbade, Belize, Bermudes, Bhoutan,
    Bolivie, Bonaire, Bresil, Brunei Darussalam, Cambodge, Canaries, Cayman, Chili, Chine, Colombie, Cook, Corée du Nord, Corée du Sud,
    Costa Rica, Cuba, Curacao, Dominicaine (République), Dominique, El Salvador, Equateur, Féroe (Iles), Fidji, Géorgie du sud, Grenade, Groenland,
    Guam, Guatemala, Guyana, Haiti, Honduras, Hong Kong, Inde, Indonésie, Jamaique, Japon, Kazakhstan, Kirghizistan, Kiribati,
    Koweit, Laos, Macao, Malaisie, Maldives, Marshall (îles), Mexique, Micronésie, Mongolie, Montserrat, Myanmar, Nauru, Népal,
    Nicaragua, Nouvelle Zélande, Oman, Ouzbékistan, Pakistan, Palau, Palestine, Panama, Papouasie Nlle Guinée, Paraguay, Pérou,
    Philippines, Saba, Saint Christophe & Névis, Saint Eustache, Saint Martin (partie hollandaise), Saint Thomas,
    Saint Vincent & Grenadines, Sainte Croix, Sainte Lucie, Saipan (Iles Mariannes), Salomon, Samoa, Samoa Américaines, Singapour,
    Sri Lanka, Surinam, Tadjikistan, Taiwan, Thailande, Timor Oriental, Tonga (Iles), Trinité & Tobago, Turkménistan,
    Turques & Caiques, Tuvalu, Uruguay, Vanuatu, Vénézuela, Vierges Américaines (îles), Vierges Britanniques (îles), Vietnam.

    2°) DEPUIS ['GP' Guadeloupe, 'MQ' Martinique, 'BL' Saint-Barthélemy, 'MF' Saint-Martin]:
    Pays en zone A:
    Antigua, Antilles Néerlandaises, Barbade, Dominique, Etats-Unis, Grenade, Guyana, Haiti, Montserrat,
    Saint-Christophe et Névis, Saint-Vincent, Sainte-Lucie, Trinité, Iles Vierges
    Pays en zone B: reste du monde

    3°) DEPUIS ['GF' Guyanne]:
    Pays en zone A: Guyana, Haiti, Sainte-Lucie
    Pays en zone B: reste du monde

    4°) DEPUIS ['RE' Réunion, 'YT' Mayotte]:
    Pays en zone A: Afrique du Sud, Comores, Kenya, Madagascar, Maurice, Seychelles
    Pays en zone B: reste du monde

    5°) DEPUIS ['PM' St Pierre & Miquelon]:
    Pays en zone A: ø
    Pays en zone B: reste du monde

    Table des caratéristiques du pays de destination
    'code_pays' => (n° de zone colissimo: depuis [FR,FX], depuis [GP,MQ,BL,MF], depuis [GF], depuis [RE,YT], depuis [PM],
                    PoidsMaxAutorisé, SuiviDestination, ImprimeCN23, MontantMaxCRBT, AvisReception, Libellé du pays)

    Mettre un commentaire devant les lignes où vous ne souhaitez pas expédier à l'International (ou encore mettre -1 comme n° de zone).
  */
  protected $pays_desc = array (
    'AE' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'ÉMIRATS ARABES UNIS'),
    'AF' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'AFGHANISTAN'),
    'AG' => array( 4,  1,  2,  2,  2, 10, 0, 1,    0, 0, 'ANTIGUA ET BARBUDA'),
    'AI' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'ANGUILLA'),
    'AL' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'ALBANIE'),
    'AM' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'ARMÉNIE'),
    'AN' => array( 4,  1,  2,  2,  2, 20, 0, 1,    0, 1, 'ANTILLES NÉERLANDAISES'), // BONNAIRE, CURACAO, SABA, ST EUSTACHE, SINT-MAARTEN
    'AO' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'ANGOLA'),
    'AQ' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'ANTARCTIQUE'),
    'AR' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'ARGENTINE'),
    'AS' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'SAMOA AMÉRICAINES'),
    'AT' => array( 1,  2,  2,  2,  2, 30, 1, 0, 1500, 0, 'AUTRICHE'),
    'AU' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'AUSTRALIE'),
    'AW' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'ARUBA'),
    'AX' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'ÅLAND, ÎLES'),
    'AZ' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'AZERBAIDJAN'),
    'BA' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'BOSNIE - HERZÉGOVINE'),
    'BB' => array( 4,  1,  2,  2,  2, 20, 0, 1,    0, 1, 'BARBADE'),
    'BD' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'BANGLADESH'),
    'BE' => array( 1,  2,  2,  2,  2, 30, 1, 0, 1500, 0, 'BELGIQUE'),
    'BF' => array( 3,  2,  2,  2,  2, 30, 1, 1,  600, 1, 'BURKINA FASO'),
    'BG' => array( 2,  2,  2,  2,  2, 30, 0, 0,    0, 1, 'BULGARIE'),
    'BH' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'BAHREIN'),
    'BI' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'BURUNDI'),
    'BJ' => array( 4,  2,  2,  2,  2, 30, 0, 1,  600, 1, 'BÉNIN'),
    'BM' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'BERMUDES'),
    'BN' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'BRUNEÏ DARUSSALAM'),
    'BO' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'BOLIVIE'),
    'BR' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'BRÉSIL'),
    'BS' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'BAHAMAS'),
    'BT' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'BHOUTAN'),
    'BV' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'BOUVET, ÎLE'),
    'BW' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'BOTSWANA'),
    'BY' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'BIÉLORUSSIE'),
    'BZ' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'BÉLIZE'),
    'CA' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'CANADA'),
    'CC' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'COCOS (ÎLES KEELING)'),
    'CD' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'CONGO (RÉPUBLIQUE DÉMOCRATIQUE DU)'), // ZAÏRE
    'CF' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'CENTRAFRIQUE'),
    'CG' => array( 3,  2,  2,  2,  2, 20, 0, 1,  600, 1, 'CONGO'),
    'CH' => array( 1,  2,  2,  2,  2, 30, 0, 1, 1500, 0, 'SUISSE'),
    'CI' => array( 3,  2,  2,  2,  2, 30, 0, 1,  600, 0, 'CÔTE D´IVOIRE'),
    'CK' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'COOK (ÎLES)'),
    'CL' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'CHILI'),
    'CM' => array( 3,  2,  2,  2,  2, 30, 0, 1,  600, 1, 'CAMEROUN'),
    'CN' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'CHINE'),
    'CO' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'COLOMBIE'),
    'CR' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'COSTA RICA'),
    'CU' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'CUBA'),
    'CV' => array( 3,  2,  2,  2,  2, 30, 0, 1, 1500, 1, 'CAP VERT'),
    'CX' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'CHRISTMAS (ÎLES)'),
    'CY' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 0, 'CHYPRE'),
    'CZ' => array( 1,  2,  2,  2,  2, 20, 0, 0,    0, 0, 'TCHÈQUE (RÉPUBLIQUE)'),
    'DE' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 0, 'ALLEMAGNE'),
    'DJ' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'DJIBOUTI'),
    'DK' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 0, 'DANEMARK'),
    'DM' => array( 4,  1,  2,  2,  2, 20, 0, 1,    0, 0, 'DOMINIQUE (ÎLE DE LA)'),
    'DO' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'DOMINICAINE (RÉPUBLIQUE)'),
    'DZ' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'ALGÉRIE'),
    'EC' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'ÉQUATEUR'),
    'EE' => array( 1,  2,  2,  2,  2, 20, 0, 0,    0, 1, 'ESTONIE'),
    'EG' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'ÉGYPTE'),
    'EH' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'SAHARA OCCIDENTAL'),
    'ER' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'ÉRYTHRÉE'),
    'ES' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 0, 'ESPAGNE'), // MELLILA, CEUTA
    'ET' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'ÉTHIOPIE'),
    'FI' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 0, 'FINLANDE'),
    'FJ' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'FIDJI'),
    'FK' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'FALKLAND, ÎLES (MALVINAS)'),
    'FM' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'MICRONÉSIE, ÉTATS FÉDÉRÉS DE'),
    'FO' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'FÉROÉ (ÎLES)'),
    'GA' => array( 3,  2,  2,  2,  2, 20, 0, 1,  600, 1, 'GABON'),
    'GB' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 0, 'GRANDE BRETAGNE'), // ROYAUME-UNI
    'GD' => array( 4,  1,  2,  2,  2, 10, 0, 1,    0, 0, 'GRENADE'),
    'GE' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'GÉORGIE'),
    'GG' => array( 1,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'GUERNESEY'),
    'GH' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'GHANA'),
    'GI' => array( 1,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'GIBRALTAR'),
    'GL' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'GRÖENLAND'),
    'GM' => array( 3,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'GAMBIE'),
    'GN' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'GUINÉE (RÉPUBLIQUE DE)'),
    'GQ' => array( 3,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'GUINÉE ÉQUATORIALE'),
    'GR' => array( 1,  2,  2,  2,  2, 20, 1, 0,    0, 0, 'GRÈCE'),
    'GS' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'GÉORGIE DU SUD ET LES ÎLES SANDWICH DU SUD'),
    'GT' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'GUATÉMALA'),
    'GU' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'GUAM'),
    'GW' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'GUINÉE BISSAU'),
    'GY' => array( 4,  1,  1,  2,  2, 20, 0, 1,    0, 1, 'GUYANA'),
    'HK' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'HONG KONG'),
    'HM' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'HEARD, ÎLE ET MCDONALD, ÎLES'),
    'HN' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'HONDURAS'),
    'HR' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'CROATIE'),
    'HT' => array( 4,  1,  1,  2,  2, 25, 0, 1,    0, 1, 'HAÎTI'),
    'HU' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 0, 'HONGRIE'),
    'IC' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'CANARIES'),
    'ID' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'INDONÉSIE'),
    'IE' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 0, 'IRLANDE'),
    'IL' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'ISRAËL'),
    'IM' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'ÎLE DE MAN'),
    'IN' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'INDE'),
    'IO' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'OCÉAN INDIEN, TERRITOIRE BRITANNIQUE DE L´'),
    'IQ' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'IRAK'),
    'IR' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'IRAN, RÉPUBLIQUE ISLAMIQUE D´'),
    'IS' => array( 2,  2,  2,  2,  2, 30, 0, 1, 1500, 1, 'ISLANDE'),
    'IT' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 0, 'ITALIE'),
    'JE' => array( 1,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'JERSEY'),
    'JM' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 0, 'JAMAÎQUE'),
    'JO' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'JORDANIE'),
    'JP' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'JAPON'),
    'KE' => array( 4,  2,  2,  1,  2, 30, 0, 1,    0, 1, 'KENYA'),
    'KG' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'KIRGHIZISTAN'),
    'KH' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'CAMBODGE'),
    'KI' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'KIRIBATI'),
    'KM' => array( 3,  2,  2,  1,  2, 20, 0, 1,    0, 1, 'COMORES'),
    'KN' => array( 4,  1,  2,  2,  2, 20, 0, 1,    0, 0, 'ST CHRISTOPHE ET NÉVIS'),
    'KP' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'COREE DU NORD (RÉPUBLIQUE POPULAIRE DÉMOCRATIQUE DE)'),
    'KR' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'COREE DU SUD (RÉPUBLIQUE DE)'),
    'KW' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'KOWEÏT'),
    'KY' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'CAÏMANES, ÎLES'),
    'KZ' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'KAZAKHSTAN'),
    'LA' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'LAOS, RÉPUBLIQUE DÉMOCRATIQUE POPULAIRE'),
    'LB' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'LIBAN'),
    'LC' => array( 4,  1,  1,  2,  2, 20, 0, 1,    0, 0, 'STE LUCIE'),
    'LI' => array( 1,  2,  2,  2,  2, 30, 0, 1, 1500, 1, 'LIECHTENSTEIN'),
    'LK' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'SRI LANKA'),
    'LR' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'LIBÉRIA'),
    'LS' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'LÉSOTHO'),
    'LT' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 1, 'LITUANIE'),
    'LU' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 0, 'LUXEMBOURG'),
    'LV' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1500, 1, 'LETTONIE'),
    'LY' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'LIBYE (JAMAHIRIYA LIBYENNE)'),
    'MA' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'MAROC'),
    'MD' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'MOLDAVIE, RÉPUBLIQUE DE'),
    'ME' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'MONTÉNÉGRO'),
    'MG' => array( 3,  2,  2,  1,  2, 30, 0, 1,    0, 1, 'MADAGASCAR'),
    'MH' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'MARSHALL (ÎLES)'),
    'MI' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'ST MARTIN (PARTIE NÉERLANDAISE)'),
    'MK' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'MACÉDOINE, L´EX-RÉPUBLIQUE YOUGOSLAVE DE'),
    'ML' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'MALI'),
    'MM' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'MYANMAR'),
    'MN' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'MONGOLIE'),
    'MO' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'MACAO'),
    'MP' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'SAÏPAN (ÎLES MARIANNES)'),
    'MP' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'MARIANNES DU NORD, ÎLES'),
    'MR' => array( 3,  2,  2,  2,  2, 20, 0, 1,  600, 0, 'MAURITANIE'),
    'MS' => array( 4,  1,  2,  2,  2, 20, 0, 1,    0, 1, 'MONTSERRAT'),
    'MT' => array( 1,  2,  2,  2,  2, 20, 0, 0,    0, 1, 'MALTE'),
    'MU' => array( 3,  2,  2,  1,  2, 30, 0, 1,    0, 1, 'MAURICE'),
    'MV' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'MALDIVES'),
    'MW' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'MALAWI'),
    'MX' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'MEXIQUE'),
    'MY' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'MALAISIE'),
    'MZ' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'MOZAMBIQUE'),
    'NA' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'NAMIBIE'),
    'NE' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'NIGER'),
    'NF' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'NORFOLK (ÎLE)'),
    'NG' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'NIGÉRIA'),
    'NI' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'NICARAGUA'),
    'NL' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 0, 'PAYS BAS'),
    'NO' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'NORVÈGE'),
    'NP' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'NÉPAL'),
    'NR' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'NAURU'),
    'NZ' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'NOUVELLE ZÉLANDE'),
    'OM' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'OMAN'),
    'PA' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'PANAMA'),
    'PE' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'PÉROU'),
    'PG' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'PAPOUASIE NOUVELLE-GUINÉE'),
    'PH' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'PHILIPPINES'),
    'PK' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'PAKISTAN'),
    'PL' => array( 1,  2,  2,  2,  2, 20, 0, 0,    0, 0, 'POLOGNE'),
    'PN' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 0, 'PITCAIRN'),
    'PR' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'PORTO RICO'),
    'PS' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'PALESTINIEN OCCUPÉ, TERRITOIRE'),
    'PT' => array( 1,  2,  2,  2,  2, 30, 0, 0, 1000, 0, 'PORTUGAL'),
    'PW' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'PALAOS'),
    'PY' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'PARAGUAY'),
    'QA' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'QATAR'),
    'RO' => array( 2,  2,  2,  2,  2, 30, 0, 0,    0, 1, 'ROUMANIE'),
    'RS' => array( 2,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'SERBIE - KOSOVO'),
    'RU' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'RUSSIE'),
    'RW' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'RWANDA'),
    'SA' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'ARABIE SAOUDITE'),
    'SB' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'SALOMON, ÎLES'),
    'SC' => array( 3,  2,  2,  1,  2, 30, 0, 1,    0, 1, 'SEYCHELLES'),
    'SD' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'SOUDAN'),
    'SE' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 0, 'SUÈDE'),
    'SG' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'SINGAPOUR'),
    'SH' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'STE HÉLÈNE'),
    'SI' => array( 1,  2,  2,  2,  2, 30, 0, 0,    0, 1, 'SLOVÉNIE'),
    'SJ' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'SVALBARD ET ÎLE JAN MAYEN'),
    'SK' => array( 1,  2,  2,  2,  2, 15, 0, 0,    0, 0, 'SLOVAQUIE'),
    'SL' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'SIERRA LÉONE'),
    'SM' => array( 1,  2,  2,  2,  2, 20, 0, 0, 1500, 1, 'SAN MARIN'),
    'SN' => array( 3,  2,  2,  2,  2, 20, 0, 1,  600, 1, 'SÉNÉGAL'),
    'SO' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'SOMALIE'),
    'SR' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'SURINAM'),
    'ST' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'SAO TOMÉ ET PRINCIPE'),
    'SV' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'EL SALVADOR'),
    'SY' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'SYRIE'),
    'SZ' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'SWAZILAND'),
    'TC' => array( 4,  2,  2,  2,  2,  5, 0, 1,    0, 0, 'TURQUES ET CAIQUES, ÎLES'),
    'TD' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'TCHAD'),
    'TG' => array( 3,  2,  2,  2,  2, 20, 0, 1,  600, 1, 'TOGO'),
    'TH' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'THAÏLANDE'),
    'TJ' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'TADJIKISTAN'),
    'TK' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'TOKELAU'),
    'TL' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'TIMOR-LESTE'),
    'TM' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'TURKMÉNISTAN'),
    'TN' => array( 2,  2,  2,  2,  2, 30, 0, 1, 1500, 0, 'TUNISIE'),
    'TO' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'TONGA (ÎLES)'),
    'TR' => array( 2,  2,  2,  2,  2, 30, 0, 1, 1000, 0, 'TURQUIE'),
    'TT' => array( 4,  1,  2,  2,  2, 20, 0, 1,    0, 0, 'TRINITÉ ET TOBAGO'),
    'TV' => array( 4,  2,  2,  2,  2, 25, 0, 1,    0, 1, 'TUVALU'),
    'TW' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'TAÏWAN'),
    'TZ' => array( 3,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'TANZANIE'),
    'UA' => array( 2,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'UKRAINE'),
    'UG' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'OUGANDA'),
    'UM' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'ÎLES MINEURES ÉLOIGNÉES DES ÉTATS-UNIS'),
    'US' => array( 3,  1,  2,  2,  2, 30, 1, 1,  200, 0, 'ÉTATS-UNIS'),
    'UY' => array( 4,  2,  2,  2,  2, 30, 0, 1,    0, 0, 'URUGUAY'),
    'UZ' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'OUZBÉKISTAN'),
    'VA' => array( 1,  2,  2,  2,  2, 20, 0, 0, 1500, 1, 'VATICAN (SAINT-SIÈGE)'),
    'VC' => array( 4,  1,  2,  2,  2, 10, 0, 1,    0, 1, 'ST VINCENT ET LES GRENADINES'),
    'VE' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'VÉNÉZUELA'),
    'VG' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 0, 'VIERGES BRITANNIQUES (ÎLES)'),  // TORTOLA
    'VI' => array( 4,  1,  2,  2,  2, 30, 0, 1,    0, 0, 'VIERGES AMÉRICAINES (ÎLES)'),  // SAINT-JOHN, SAINT-THOMAS, SAINTE-CROIX
    'VN' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'VIET NAM'),
    'VU' => array( 4,  2,  2,  2,  2, 20, 0, 1,    0, 1, 'VANUATU'),
    'WS' => array( 4,  2,  2,  2,  2, 10, 0, 1,    0, 1, 'SAMOA'),
    'YE' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'YÉMEN'),
    'ZA' => array( 3,  2,  2,  1,  2, 30, 0, 1,    0, 0, 'AFRIQUE DU SUD'),
    'ZM' => array( 3,  2,  2,  2,  2, 30, 0, 1,    0, 1, 'ZAMBIE'),
    'ZW' => array( 3,  2,  2,  2,  2, 20, 1, 1,    0, 0, 'ZIMBABWE')
  );

  /* Paramètres en BDD */
  protected $tax_class_id;
  protected $taux;
  protected $en_dehors_UE;
  protected $avec_avis_reception;
  protected $ad_valorem;
  protected $avec_delais;
  protected $details_affichage;

  protected $trop_lourd;
  protected $use_taxes;

  protected $adresse;
  protected $poids_unitaire;
  protected $nb_boites;
  protected $sub_total;

  protected $origin_iso_code_2;
  protected $dest_iso_code_2;

  protected $quote_data = array();
  protected $quote_error;

  protected function _add_method($method_full_name, $offre_id, $tarif_name, $taux, $delai = FALSE) {

    if (!isset($this->offre) or !is_array($this->offre)) return;
    if (!array_key_exists($offre_id, $this->offre)) return;
    if (!array_key_exists('tarifs', $this->offre[$offre_id])) return;
    if (!array_key_exists($tarif_name, $this->offre[$offre_id]['tarifs'])) return;

    /* Si cette méthode d'expédition n'est pas permise, return */
    if ($this->config->get('colissimo_' . $method_full_name . '_enabled') == FALSE) return;

    $is_inter = ((strpos($this->offre[$offre_id]['code'], 'inter') !== FALSE) ? TRUE : FALSE);

    if ($is_inter) {
      $max_poids = $this->pays_desc[$this->dest_iso_code_2][5];
      $imprime_cn23 = ($this->pays_desc[$this->dest_iso_code_2][7] ? TRUE : FALSE);
      $max_crbt = $this->pays_desc[$this->dest_iso_code_2][8];
      $with_avis = $this->avec_avis_reception and ($this->pays_desc[$this->dest_iso_code_2][9] ? TRUE : FALSE);
      $ad_valorem = $this->ad_valorem;
    } else {
      $max_poids = self::MODULE_SHIPPING_COLISSIMO_MAX_POIDS;
      $imprime_cn23 = FALSE;
      $max_crbt = self::MODULE_SHIPPING_COLISSIMO_MAX_CRBT;
      $with_avis = $this->avec_avis_reception;
      $ad_valorem = FALSE;
    }

    /* Calcul du coût d'un colis. */
    $shipping = -1;
    if ($this->poids_unitaire <= $max_poids) { /* Limitation du poids unitaire */
      /* Comparaison du poids d'un colis avec chaque entrée dans la table */
      $duos = explode(',', $this->offre[$offre_id]['tarifs'][$tarif_name]);
      foreach ($duos as $duo) {
        $data = explode(':', $duo);
        if ($this->poids_unitaire <= $data[0]) {
          if (isset($data[1])) $shipping = $data[1];
          break;
        }
      }
    }

    /* Pour cette méthode, le poids unitaire calculé d'un colis dépasse le maximum de la table. On ne l'affichera pas. */
    if ($shipping == -1) {
      if ($this->trop_lourd == -1) $this->trop_lourd = 1;
      return;
    }
    else $this->trop_lourd = 0;

    $is_economic = ((strpos($method_full_name, 'econom') !== FALSE) ? TRUE : FALSE);
    $with_recommendation = ((strpos($method_full_name, 'recomm') !== FALSE) ? TRUE : FALSE);
    $is_internet = ((strpos($method_full_name, 'internet') !== FALSE) ? TRUE : FALSE);
    $with_crbt = ((strpos($method_full_name, 'crbt') !== FALSE) ? TRUE : FALSE);

    $libel = '';  /* Normal */
    if ($is_internet)  {
      $libel = self::MODULE_SHIPPING_COLISSIMO_MARK_INTERNET . $this->language->get('mesg_colissimo_text_internet');
    }

    if ($is_economic)  {
      $libel = self::MODULE_SHIPPING_COLISSIMO_MARK_ECO . $this->language->get('mesg_colissimo_text_eco');
    }
    else if ($with_recommendation) {

      if (strcmp($taux, 'Auto') == 0) {
        /* Pour du multicolis, la recommandation pour chaque colis sera
           supérieure à ce qu'elle devrait être puisque l'on ne connait pas la
           valeur de chaque colis et que l'on calcule à partir du total commande. */
        $order_total_amount = $this->sub_total;
        /* En EUROS. Adapter si besoin */
        if ($order_total_amount <= 50) $taux = 'R1';
        elseif ($order_total_amount <= 200) $taux = 'R2';
        elseif ($order_total_amount <= 400) $taux = 'R3';
        elseif ($order_total_amount <= 600) $taux = 'R4';
        elseif ($order_total_amount <= 800) $taux = 'R5';
        else $taux = 'R5';
      }

      if (strcmp($taux, 'R1') == 0) {
        $libel .= ', +R1' . $this->language->get('mesg_colissimo_text_rec');
        $shipping += self::MODULE_SHIPPING_COLISSIMO_SUPP_R1;
      }
      else if (strcmp($taux, 'R2') == 0) {
        $libel .= ', +R2' . $this->language->get('mesg_colissimo_text_rec');
        $shipping += self::MODULE_SHIPPING_COLISSIMO_SUPP_R2;
      }
      else if (strcmp($taux, 'R3') == 0) {
        $libel .= ', +R3' . $this->language->get('mesg_colissimo_text_rec');
        $shipping += self::MODULE_SHIPPING_COLISSIMO_SUPP_R3;
      }
      else if (strcmp($taux, 'R4') == 0) {
        $libel .= ', +R4' . $this->language->get('mesg_colissimo_text_rec');
        $shipping += self::MODULE_SHIPPING_COLISSIMO_SUPP_R4;
      }
      else if (strcmp($taux, 'R5') == 0) {
        $libel .= ', +R5' . $this->language->get('mesg_colissimo_text_rec');
        $shipping += self::MODULE_SHIPPING_COLISSIMO_SUPP_R5;
      }
    }

    /* Remise pour affranchissement en ligne */
    if ($is_internet) {
      $shipping *= (1 - (self::MODULE_SHIPPING_COLISSIMO_INTERNET_PERCENT/100));
    }

    if ($with_recommendation and $with_avis) {
      $libel .= self::MODULE_SHIPPING_COLISSIMO_MARK_AR . $this->language->get('mesg_colissimo_text_ar');
      $shipping += self::MODULE_SHIPPING_COLISSIMO_SUPP_AVIS_RECEPTION;
    }

    if (!$is_internet and $with_crbt) {
      $libel .= self::MODULE_SHIPPING_COLISSIMO_MARK_CRBT . $this->language->get('mesg_colissimo_text_crbt');
      $shipping += $this->offre[$offre_id]['crbt'];
    }

    if ($ad_valorem) {
      /* Assurance complémentaire par tranche de xxx EUR (International).
         Pour du multicolis, le prix de l'assurance sera supérieur à ce qu'il devrait
         être puisque le programme ne connait pas la valeur de chaque colis. */
      $order_total_amount = $this->sub_total;
      if ($order_total_amount > self::MODULE_SHIPPING_COLISSIMO_MAX_AD_VALOREM) $order_total_amount = self::MODULE_SHIPPING_COLISSIMO_MAX_AD_VALOREM;
      if (self::MODULE_SHIPPING_COLISSIMO_TRANCHE_AD_VALOREM != 0) $coefficient = (int)ceil($order_total_amount / self::MODULE_SHIPPING_COLISSIMO_TRANCHE_AD_VALOREM);
      else $coeficient = 0;
      $libel .= self::MODULE_SHIPPING_COLISSIMO_MARK_AD_VALOREM . strval($coefficient * self::MODULE_SHIPPING_COLISSIMO_TRANCHE_AD_VALOREM);
      $shipping += $coefficient * self::MODULE_SHIPPING_COLISSIMO_SUPP_AD_VALOREM;
    }

    /* Frais fixes selon le poids */
    $frais = 0;
    $duos = explode(',', $this->config->get('colissimo_handling'));
    foreach ($duos as $duo) {
      $data = explode(':', $duo);
      if (isset($data[1])) $frais = $data[1];
      if ($this->poids_unitaire <= $data[0]) break;
    }
    $shipping += $frais;

    /* crbt possible ? */
    if ($with_crbt) {
      $order_total_amount = $this->sub_total;
      if (($order_total_amount + $shipping) > $max_crbt) return;
    }

    /* Delais */
    if ($delai and array_key_exists('delais', $this->offre[$offre_id])) {
      if (array_key_exists($tarif_name, $this->offre[$offre_id]['delais'])) {
        if (is_array($this->offre[$offre_id]['delais'][$tarif_name])) {
          $delai_str = sprintf($this->language->get('mesg_colissimo_delay_range'), $this->offre[$offre_id]['delais'][$tarif_name][0], $this->offre[$offre_id]['delais'][$tarif_name][1]);
        } else {
          $delai_str = sprintf($this->language->get('mesg_colissimo_delay_fixed'), $this->offre[$offre_id]['delais'][$tarif_name]);
        }
        $libel .= $delai_str;
      }
    }

    /* Coût pour tous les colis */
    $shipping_cost = round($shipping, 2) * $this->nb_boites;

    /* Configuration affichage */
    switch ($this->details_affichage) {
      case 0:
        $show_box_weight = '';
        break;
      case 1:
        $show_box_weight = $this->nb_boites . $this->language->get('mesg_colissimo_text_boxes');
        break;
      case 2:
        $show_box_weight = number_format($this->poids_unitaire * $this->nb_boites, 3) . self::MODULE_SHIPPING_COLISSIMO_MARK_UNITS;
        break;
      default:
        $show_box_weight = $this->nb_boites . ' x ' . number_format($this->poids_unitaire, 3) . self::MODULE_SHIPPING_COLISSIMO_MARK_UNITS;
        break;
    }

    $shipping_method = $show_box_weight . $this->language->get('mesg_colissimo_text_way') . $this->adresse['country'] . $libel;

    /* Stockage paramètres */
    $this->quote_data[$method_full_name] = array(
      'code'         => 'colissimo.'.$method_full_name,
      'title'        => $shipping_method,
      'cost'         => $this->tax->calculate($shipping_cost, $this->tax_class_id, $this->use_taxes),
      'tax_class_id' => $this->tax_class_id,
      'text'         => $this->currency->format($this->tax->calculate($shipping_cost, $this->tax_class_id, $this->use_taxes))
    );
  }

  protected function _verify_methods() {
    if ($this->trop_lourd == 1) {
      /* Le poids unitaire calculé dépassait le poids maximum dans toutes les méthodes */
      switch ($this->details_affichage) {
        case 0:
          $show_box_weight = '';
          break;
        case 1:
          $show_box_weight = $this->nb_boites . $this->language->get('mesg_colissimo_text_boxes');
          break;
        case 2:
          $show_box_weight = number_format($this->poids_unitaire * $this->nb_boites, 3) . self::MODULE_SHIPPING_COLISSIMO_MARK_UNITS;
          break;
        default:
          $show_box_weight = $this->nb_boites . ' x ' . number_format($this->poids_unitaire, 3) . self::MODULE_SHIPPING_COLISSIMO_MARK_UNITS;
          break;
      }
      $this->quote_error = $show_box_weight . $this->language->get('mesg_colissimo_too_heavy');
    }
  }

  function getQuote($address) {

    $this->load->language('shipping/colissimo');

    $this->tax_class_id        = $this->config->get('colissimo_tax_class_id');
    $this->taux                = $this->config->get('colissimo_taux_recommandation');
    $this->en_dehors_UE        = $this->config->get('colissimo_outside_ue_enabled');
    $this->avec_avis_reception = $this->config->get('colissimo_avis_reception');
    $this->ad_valorem          = $this->config->get('colissimo_international_ad_valorem');
    $this->avec_delais         = $this->config->get('colissimo_delays_enabled');
    $this->details_affichage   = $this->config->get('colissimo_box_weight_display');
    $this->trop_lourd          = -1;

    $image = 'shipping_colissimo48.gif';
    $status = TRUE;

    if ($status) {
      /* Vérification que le pays de livraison est dans la zone de taxation restreinte, sinon le module se désactive. */
      if (!$this->config->get('colissimo_tax_zone_id')) $status = TRUE;
      else {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('colissimo_tax_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");
        if ($query->num_rows) $status = TRUE;
        else $status = FALSE;
      }
    }

    $method_data = array();

    if ($status) {

      /* Tax rate for a zone / class */
      if (intval($this->tax_class_id)) $this->use_taxes = TRUE ;
      else $this->use_taxes = FALSE ;

      /* Récupération données OC */
      $this->adresse = $address;
      $this->poids_unitaire = $this->cart->getWeight();
      $this->nb_boites = 1;
      $this->sub_total = $this->cart->getSubTotal();

      /* Ajout de la tare au poids du panier */
      $tare = 0;
      $duos = explode(',', $this->config->get('colissimo_tare'));
      /* Comparaison du poids unitaire avec chaque entrée dans la table */
      foreach ($duos as $duo) {
        $data = explode(':', $duo);
        if (isset($data[1])) $tare = $data[1];
        if ($this->poids_unitaire <= $data[0]) break;
      }
      $this->poids_unitaire += $tare;
      
      /* Pays de départ */
      $this->load->model('localisation/country');
      $country_info = $this->model_localisation_country->getCountry($this->config->get('config_country_id'));
      $this->origin_iso_code_2 = $country_info['iso_code_2'];

      /* Pays de destination */
      $this->dest_iso_code_2 = $address['iso_code_2'];

      /* Correction selon code postal destinataire en cas mauvaise saisie */
      if (strcmp($this->dest_iso_code_2, 'FR') == 0 or strcmp($this->dest_iso_code_2, 'FX') == 0) {
        if (isset($address['postcode'])) {
          /* On connait le code postal */
          $dest3 = substr(trim($address['postcode']), 0, 3);

          if (strcmp($dest3, '971') == 0) $this->dest_iso_code_2 = 'GP'; /* Guadeloupe */
          elseif (strcmp($dest3, '972') == 0) $this->dest_iso_code_2 = 'MQ'; /* Martinique */
          elseif (strcmp($dest3, '973') == 0) $this->dest_iso_code_2 = 'GF'; /* Guyanne */
          elseif (strcmp($dest3, '974') == 0) $this->dest_iso_code_2 = 'RE'; /* Réunion */
          elseif (strcmp($dest3, '975') == 0) $this->dest_iso_code_2 = 'PM'; /* St Pierre & Miquelon */
          elseif (strcmp($dest3, '976') == 0) $this->dest_iso_code_2 = 'YT'; /* Mayotte */
          elseif (strcmp($dest3, '977') == 0) $this->dest_iso_code_2 = 'BL'; /* Saint-Barthélemy */
          elseif (strcmp($dest3, '978') == 0) $this->dest_iso_code_2 = 'MF'; /* Saint-Martin */
          elseif (strcmp($dest3, '984') == 0) $this->dest_iso_code_2 = 'TF'; /* Terres australes françaises */
          elseif (strcmp($dest3, '986') == 0) $this->dest_iso_code_2 = 'WF'; /* Wallis & Futuna */
          elseif (strcmp($dest3, '987') == 0) $this->dest_iso_code_2 = 'PF'; /* Polynésie française */
          elseif (strcmp($dest3, '988') == 0) $this->dest_iso_code_2 = 'NC'; /* Nouvelle Calédonie */
          elseif (strcmp($dest3, '989') == 0) $this->dest_iso_code_2 = 'CP'; /* Clipperton */
        }
      }

      /* Recherche zone du pays de destination */
      if (array_key_exists($this->origin_iso_code_2, $this->zone_france_et_domtom)) { /* depuis le territoire français */
        if (array_key_exists($this->dest_iso_code_2, $this->zone_france_et_domtom[$this->origin_iso_code_2])) {  /* vers le territoire français */
          $offre_num = $this->zone_france_et_domtom[$this->origin_iso_code_2][$this->dest_iso_code_2];
          if (($offre_num >= 0) and ($offre_num < count($this->offre))) {
            $this->_add_method('normal', $offre_num, 'normal', '', $this->avec_delais);
            $this->_add_method('econom', $offre_num, 'econom', '', $this->avec_delais);
            $this->_add_method('recomm', $offre_num, 'normal', $this->taux, $this->avec_delais);
            $this->_add_method('recomm_crbt', $offre_num, 'normal', $this->taux, $this->avec_delais);
            if (in_array($this->origin_iso_code_2, array('FR','FX'))) {
              $this->_add_method('internet', $offre_num, 'normal', $this->taux, $this->avec_delais);
              $this->_add_method('internet_recomm', $offre_num, 'normal', $this->taux, $this->avec_delais);
            }
            $this->_verify_methods();
          } else {
            $this->quote_error = $this->language->get('mesg_colissimo_invalid_destination');
          }

        } else {  /* vers International */

          $image = 'shipping_colissimo_inter.gif';
          if (($this->en_dehors_UE == FALSE) and !in_array($this->dest_iso_code_2, $this->zone_union_europeenne)) {
            $this->quote_error = $this->language->get('mesg_colissimo_invalid_destination');
          } else {

            if (array_key_exists($this->dest_iso_code_2, $this->pays_desc)) {

              switch ($this->origin_iso_code_2) {
                case 'FR': /* France */
                case 'FX': /* Métropole */
                  $offre_num = 5;
                  $dest_zone = $this->pays_desc[$this->dest_iso_code_2][0];
                  break;

                case 'GP': /* Guadeloupe */
                case 'MQ': /* Martinique */
                case 'BL': /* Saint-Barthélemy */
                case 'MF': /* Saint-Martin */
                  $offre_num = 6;
                  $dest_zone = $this->pays_desc[$this->dest_iso_code_2][1];
                  break;

                case 'GF': /* Guyanne */
                  $offre_num = 6;
                  $dest_zone = $this->pays_desc[$this->dest_iso_code_2][2];
                  break;

                case 'RE': /* Réunion */
                case 'YT': /* Mayotte */
                  $offre_num = 6;
                  $dest_zone = $this->pays_desc[$this->dest_iso_code_2][3];
                  break;

                case 'PM': /* St Pierre & Miquelon */
                  $offre_num = 6;
                  $dest_zone = $this->pays_desc[$this->dest_iso_code_2][4];
                  break;

                case 'TF': /* Terres australes françaises */
                case 'WF': /* Wallis & Futuna */
                case 'PF': /* Polynésie française */
                case 'NC': /* Nouvelle Calédonie */
                case 'CP': /* Clipperton */
                  $offre_num = -1;
                  $dest_zone = -1;
                  break;

                default:
                  $offre_num = -1;
                  $dest_zone = -1;
                  break;
              } /* end switch */

              if (($offre_num >= 5) and ($offre_num < count($this->offre))) {
                $this->_add_method('international', $offre_num, 'normal_' . $dest_zone,  '', $this->avec_delais);
                $this->_add_method('international_crbt', $offre_num, 'normal_' . $dest_zone,  '', $this->avec_delais);
                if (in_array($this->origin_iso_code_2, array('FR','FX'))) {
                  $this->_add_method('internet_international', $offre_num, 'normal_' . $dest_zone,  '', $this->avec_delais);
                }
                $this->_verify_methods();

              } else { /* Zone invalide pour ce code pays */
                $this->quote_error = $this->language->get('mesg_colissimo_invalid_destination');
              }
            } else { /* Code ISO inexistant */
              $this->quote_error = $this->language->get('mesg_colissimo_invalid_destination');
            }
          }
        }
      } else { /* Origine non supportée */
        $this->quote_error = $this->language->get('mesg_colissimo_invalid_origin');
      }
    }

    if ($this->quote_data or $this->quote_error) {
      $method_data = array(
        'code'       => 'colissimo',
        'title'      => $this->language->get('text_title').'&nbsp;<img src="image/shipping/'.$image.'" alt="" />',
        'quote'      => $this->quote_data,
        'sort_order' => $this->config->get('colissimo_sort_order'),
        'error'      => $this->quote_error
      );
    }

    return $method_data;
  }
}
?>