/*
 * Copyright (C) 2010 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.zxing.oned;

import java.util.ArrayList;
import java.util.List;

/**
 * Records EAN prefix to GS1 Member Organization, where the member organization
 * correlates strongly with a country. This is an imperfect means of identifying
 * a country of origin by EAN-13 barcode value. See
 * <a href="http://en.wikipedia.org/wiki/List_of_GS1_country_codes">
 * http://en.wikipedia.org/wiki/List_of_GS1_country_codes</a>.
 *
 * @author Sean Owen
 */
final class EANManufacturerOrgSupport {

  private final List<int[]> ranges = new ArrayList<>();
  private final List<String> countryIdentifiers = new ArrayList<>();

  String lookupCountryIdentifier(String productCode) {
    initIfNeeded();
    int prefix = Integer.parseInt(productCode.substring(0, 3));
    int max = ranges.size();
    for (int i = 0; i < max; i++) {
      int[] range = ranges.get(i);
      int start = range[0];
      if (prefix < start) {
        return null;
      }
      int end = range.length == 1 ? start : range[1];
      if (prefix <= end) {
        return countryIdentifiers.get(i);
      }
    }
    return null;
  }

  private void add(int[] range, String id) {
    ranges.add(range);
    countryIdentifiers.add(id);
  }

  private synchronized void initIfNeeded() {
    if (!ranges.isEmpty()) {
      return;
    }
    add(new int[] {0,19},    "US/CA");
    add(new int[] {30,39},   "US");
    add(new int[] {60,139},  "US/CA");
    add(new int[] {300,379}, "FR");
    add(new int[] {380},     "BG");
    add(new int[] {383},     "SI");
    add(new int[] {385},     "HR");
    add(new int[] {387},     "BA");
    add(new int[] {400,440}, "DE");
    add(new int[] {450,459}, "JP");
    add(new int[] {460,469}, "RU");
    add(new int[] {471},     "TW");
    add(new int[] {474},     "EE");
    add(new int[] {475},     "LV");
    add(new int[] {476},     "AZ");
    add(new int[] {477},     "LT");
    add(new int[] {478},     "UZ");
    add(new int[] {479},     "LK");
    add(new int[] {480},     "PH");
    add(new int[] {481},     "BY");
    add(new int[] {482},     "UA");
    add(new int[] {484},     "MD");
    add(new int[] {485},     "AM");
    add(new int[] {486},     "GE");
    add(new int[] {487},     "KZ");
    add(new int[] {489},     "HK");
    add(new int[] {490,499}, "JP");
    add(new int[] {500,509}, "GB");
    add(new int[] {520},     "GR");
    add(new int[] {528},     "LB");
    add(new int[] {529},     "CY");
    add(new int[] {531},     "MK");
    add(new int[] {535},     "MT");
    add(new int[] {539},     "IE");
    add(new int[] {540,549}, "BE/LU");
    add(new int[] {560},     "PT");
    add(new int[] {569},     "IS");
    add(new int[] {570,579}, "DK");
    add(new int[] {590},     "PL");
    add(new int[] {594},     "RO");
    add(new int[] {599},     "HU");
    add(new int[] {600,601}, "ZA");
    add(new int[] {603},     "GH");
    add(new int[] {608},     "BH");
    add(new int[] {609},     "MU");
    add(new int[] {611},     "MA");
    add(new int[] {613},     "DZ");
    add(new int[] {616},     "KE");
    add(new int[] {618},     "CI");
    add(new int[] {619},     "TN");
    add(new int[] {621},     "SY");
    add(new int[] {622},     "EG");
    add(new int[] {624},     "LY");
    add(new int[] {625},     "JO");
    add(new int[] {626},     "IR");
    add(new int[] {627},     "KW");
    add(new int[] {628},     "SA");
    add(new int[] {629},     "AE");
    add(new int[] {640,649}, "FI");
    add(new int[] {690,695}, "CN");
    add(new int[] {700,709}, "NO");
    add(new int[] {729},     "IL");
    add(new int[] {730,739}, "SE");
    add(new int[] {740},     "GT");
    add(new int[] {741},     "SV");
    add(new int[] {742},     "HN");
    add(new int[] {743},     "NI");
    add(new int[] {744},     "CR");
    add(new int[] {745},     "PA");
    add(new int[] {746},     "DO");
    add(new int[] {750},     "MX");
    add(new int[] {754,755}, "CA");
    add(new int[] {759},     "VE");
    add(new int[] {760,769}, "CH");
    add(new int[] {770},     "CO");
    add(new int[] {773},     "UY");
    add(new int[] {775},     "PE");
    add(new int[] {777},     "BO");
    add(new int[] {779},     "AR");
    add(new int[] {780},     "CL");
    add(new int[] {784},     "PY");
    add(new int[] {785},     "PE");
    add(new int[] {786},     "EC");
    add(new int[] {789,790}, "BR");
    add(new int[] {800,839}, "IT");
    add(new int[] {840,849}, "ES");
    add(new int[] {850},     "CU");
    add(new int[] {858},     "SK");
    add(new int[] {859},     "CZ");
    add(new int[] {860},     "YU");
    add(new int[] {865},     "MN");
    add(new int[] {867},     "KP");
    add(new int[] {868,869}, "TR");
    add(new int[] {870,879}, "NL");
    add(new int[] {880},     "KR");
    add(new int[] {885},     "TH");
    add(new int[] {888},     "SG");
    add(new int[] {890},     "IN");
    add(new int[] {893},     "VN");
    add(new int[] {896},     "PK");
    add(new int[] {899},     "ID");
    add(new int[] {900,919}, "AT");
    add(new int[] {930,939}, "AU");
    add(new int[] {940,949}, "AZ");
    add(new int[] {955},     "MY");
    add(new int[] {958},     "MO");
  }

}
