/*
 * Copyright 2009 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.rss;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.ResultPointCallback;
import com.google.zxing.common.BitArray;

/**
 * Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.
 */
public final class RSS14Reader extends AbstractRSSReader {

  private static final int[] OUTSIDE_EVEN_TOTAL_SUBSET = {1,10,34,70,126};
  private static final int[] INSIDE_ODD_TOTAL_SUBSET = {4,20,48,81};
  private static final int[] OUTSIDE_GSUM = {0,161,961,2015,2715};
  private static final int[] INSIDE_GSUM = {0,336,1036,1516};
  private static final int[] OUTSIDE_ODD_WIDEST = {8,6,4,3,1};
  private static final int[] INSIDE_ODD_WIDEST = {2,4,6,8};

  private static final int[][] FINDER_PATTERNS = {
      {3,8,2,1},
      {3,5,5,1},
      {3,3,7,1},
      {3,1,9,1},
      {2,7,4,1},
      {2,5,6,1},
      {2,3,8,1},
      {1,5,7,1},
      {1,3,9,1},
  };

  private final List<Pair> possibleLeftPairs;
  private final List<Pair> possibleRightPairs;

  public RSS14Reader() {
    possibleLeftPairs = new ArrayList<>();
    possibleRightPairs = new ArrayList<>();
  }

  @Override
  public Result decodeRow(int rowNumber,
                          BitArray row,
                          Map<DecodeHintType,?> hints) throws NotFoundException {
    Pair leftPair = decodePair(row, false, rowNumber, hints);
    addOrTally(possibleLeftPairs, leftPair);
    row.reverse();
    Pair rightPair = decodePair(row, true, rowNumber, hints);
    addOrTally(possibleRightPairs, rightPair);
    row.reverse();
    int lefSize = possibleLeftPairs.size();
    for (int i = 0; i < lefSize; i++) {
      Pair left = possibleLeftPairs.get(i);
      if (left.getCount() > 1) {
        int rightSize = possibleRightPairs.size();
        for (int j = 0; j < rightSize; j++) {
          Pair right = possibleRightPairs.get(j);
          if (right.getCount() > 1) {
            if (checkChecksum(left, right)) {
              return constructResult(left, right);
            }
          }
        }
      }
    }
    throw NotFoundException.getNotFoundInstance();
  }

  private static void addOrTally(Collection<Pair> possiblePairs, Pair pair) {
    if (pair == null) {
      return;
    }
    boolean found = false;
    for (Pair other : possiblePairs) {
      if (other.getValue() == pair.getValue()) {
        other.incrementCount();
        found = true;
        break;
      }
    }
    if (!found) {
      possiblePairs.add(pair);
    }
  }

  @Override
  public void reset() {
    possibleLeftPairs.clear();
    possibleRightPairs.clear();
  }

  private static Result constructResult(Pair leftPair, Pair rightPair) {
    long symbolValue = 4537077L * leftPair.getValue() + rightPair.getValue();
    String text = String.valueOf(symbolValue);

    StringBuilder buffer = new StringBuilder(14);
    for (int i = 13 - text.length(); i > 0; i--) {
      buffer.append('0');
    }
    buffer.append(text);

    int checkDigit = 0;
    for (int i = 0; i < 13; i++) {
      int digit = buffer.charAt(i) - '0';
      checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;
    }
    checkDigit = 10 - (checkDigit % 10);
    if (checkDigit == 10) {
      checkDigit = 0;
    }
    buffer.append(checkDigit);

    ResultPoint[] leftPoints = leftPair.getFinderPattern().getResultPoints();
    ResultPoint[] rightPoints = rightPair.getFinderPattern().getResultPoints();
    return new Result(
        String.valueOf(buffer.toString()),
        null,
        new ResultPoint[] { leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1], },
        BarcodeFormat.RSS_14);
  }

  private static boolean checkChecksum(Pair leftPair, Pair rightPair) {
    //int leftFPValue = leftPair.getFinderPattern().getValue();
    //int rightFPValue = rightPair.getFinderPattern().getValue();
    //if ((leftFPValue == 0 && rightFPValue == 8) ||
    //    (leftFPValue == 8 && rightFPValue == 0)) {
    //}
    int checkValue = (leftPair.getChecksumPortion() + 16 * rightPair.getChecksumPortion()) % 79;
    int targetCheckValue =
        9 * leftPair.getFinderPattern().getValue() + rightPair.getFinderPattern().getValue();
    if (targetCheckValue > 72) {
      targetCheckValue--;
    }
    if (targetCheckValue > 8) {
      targetCheckValue--;
    }
    return checkValue == targetCheckValue;
  }

  private Pair decodePair(BitArray row, boolean right, int rowNumber, Map<DecodeHintType,?> hints) {
    try {
      int[] startEnd = findFinderPattern(row, 0, right);
      FinderPattern pattern = parseFoundFinderPattern(row, rowNumber, right, startEnd);

      ResultPointCallback resultPointCallback = hints == null ? null :
        (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);

      if (resultPointCallback != null) {
        float center = (startEnd[0] + startEnd[1]) / 2.0f;
        if (right) {
          // row is actually reversed
          center = row.getSize() - 1 - center;
        }
        resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber));
      }

      DataCharacter outside = decodeDataCharacter(row, pattern, true);
      DataCharacter inside = decodeDataCharacter(row, pattern, false);
      return new Pair(1597 * outside.getValue() + inside.getValue(),
                      outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),
                      pattern);
    } catch (NotFoundException ignored) {
      return null;
    }
  }

  private DataCharacter decodeDataCharacter(BitArray row, FinderPattern pattern, boolean outsideChar)
      throws NotFoundException {

    int[] counters = getDataCharacterCounters();
    counters[0] = 0;
    counters[1] = 0;
    counters[2] = 0;
    counters[3] = 0;
    counters[4] = 0;
    counters[5] = 0;
    counters[6] = 0;
    counters[7] = 0;

    if (outsideChar) {
      recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
    } else {
      recordPattern(row, pattern.getStartEnd()[1] + 1, counters);
      // reverse it
      for (int i = 0, j = counters.length - 1; i < j; i++, j--) {
        int temp = counters[i];
        counters[i] = counters[j];
        counters[j] = temp;
      }
    }

    int numModules = outsideChar ? 16 : 15;
    float elementWidth = (float) count(counters) / (float) numModules;

    int[] oddCounts = this.getOddCounts();
    int[] evenCounts = this.getEvenCounts();
    float[] oddRoundingErrors = this.getOddRoundingErrors();
    float[] evenRoundingErrors = this.getEvenRoundingErrors();

    for (int i = 0; i < counters.length; i++) {
      float value = (float) counters[i] / elementWidth;
      int count = (int) (value + 0.5f); // Round
      if (count < 1) {
        count = 1;
      } else if (count > 8) {
        count = 8;
      }
      int offset = i / 2;
      if ((i & 0x01) == 0) {
        oddCounts[offset] = count;
        oddRoundingErrors[offset] = value - count;
      } else {
        evenCounts[offset] = count;
        evenRoundingErrors[offset] = value - count;
      }
    }

    adjustOddEvenCounts(outsideChar, numModules);

    int oddSum = 0;
    int oddChecksumPortion = 0;
    for (int i = oddCounts.length - 1; i >= 0; i--) {
      oddChecksumPortion *= 9;
      oddChecksumPortion += oddCounts[i];
      oddSum += oddCounts[i];
    }
    int evenChecksumPortion = 0;
    int evenSum = 0;
    for (int i = evenCounts.length - 1; i >= 0; i--) {
      evenChecksumPortion *= 9;
      evenChecksumPortion += evenCounts[i];
      evenSum += evenCounts[i];
    }
    int checksumPortion = oddChecksumPortion + 3*evenChecksumPortion;

    if (outsideChar) {
      if ((oddSum & 0x01) != 0 || oddSum > 12 || oddSum < 4) {
        throw NotFoundException.getNotFoundInstance();
      }
      int group = (12 - oddSum) / 2;
      int oddWidest = OUTSIDE_ODD_WIDEST[group];
      int evenWidest = 9 - oddWidest;
      int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, false);
      int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, true);
      int tEven = OUTSIDE_EVEN_TOTAL_SUBSET[group];
      int gSum = OUTSIDE_GSUM[group];
      return new DataCharacter(vOdd * tEven + vEven + gSum, checksumPortion);
    } else {
      if ((evenSum & 0x01) != 0 || evenSum > 10 || evenSum < 4) {
        throw NotFoundException.getNotFoundInstance();
      }
      int group = (10 - evenSum) / 2;
      int oddWidest = INSIDE_ODD_WIDEST[group];
      int evenWidest = 9 - oddWidest;
      int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
      int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
      int tOdd = INSIDE_ODD_TOTAL_SUBSET[group];
      int gSum = INSIDE_GSUM[group];
      return new DataCharacter(vEven * tOdd + vOdd + gSum, checksumPortion);
    }

  }

  private int[] findFinderPattern(BitArray row, int rowOffset, boolean rightFinderPattern)
      throws NotFoundException {

    int[] counters = getDecodeFinderCounters();
    counters[0] = 0;
    counters[1] = 0;
    counters[2] = 0;
    counters[3] = 0;

    int width = row.getSize();
    boolean isWhite = false;
    while (rowOffset < width) {
      isWhite = !row.get(rowOffset);
      if (rightFinderPattern == isWhite) {
        // Will encounter white first when searching for right finder pattern
        break;
      }
      rowOffset++;
    }

    int counterPosition = 0;
    int patternStart = rowOffset;
    for (int x = rowOffset; x < width; x++) {
      if (row.get(x) ^ isWhite) {
        counters[counterPosition]++;
      } else {
        if (counterPosition == 3) {
          if (isFinderPattern(counters)) {
            return new int[]{patternStart, x};
          }
          patternStart += counters[0] + counters[1];
          counters[0] = counters[2];
          counters[1] = counters[3];
          counters[2] = 0;
          counters[3] = 0;
          counterPosition--;
        } else {
          counterPosition++;
        }
        counters[counterPosition] = 1;
        isWhite = !isWhite;
      }
    }
    throw NotFoundException.getNotFoundInstance();

  }

  private FinderPattern parseFoundFinderPattern(BitArray row, int rowNumber, boolean right, int[] startEnd)
      throws NotFoundException {
    // Actually we found elements 2-5
    boolean firstIsBlack = row.get(startEnd[0]);
    int firstElementStart = startEnd[0] - 1;
    // Locate element 1
    while (firstElementStart >= 0 && firstIsBlack ^ row.get(firstElementStart)) {
      firstElementStart--;
    }
    firstElementStart++;
    int firstCounter = startEnd[0] - firstElementStart;
    // Make 'counters' hold 1-4
    int[] counters = getDecodeFinderCounters();
    System.arraycopy(counters, 0, counters, 1, counters.length - 1);
    counters[0] = firstCounter;
    int value = parseFinderValue(counters, FINDER_PATTERNS);
    int start = firstElementStart;
    int end = startEnd[1];
    if (right) {
      // row is actually reversed
      start = row.getSize() - 1 - start;
      end = row.getSize() - 1 - end;
    }
    return new FinderPattern(value, new int[] {firstElementStart, startEnd[1]}, start, end, rowNumber);
  }

  private void adjustOddEvenCounts(boolean outsideChar, int numModules) throws NotFoundException {

    int oddSum = count(getOddCounts());
    int evenSum = count(getEvenCounts());
    int mismatch = oddSum + evenSum - numModules;
    boolean oddParityBad = (oddSum & 0x01) == (outsideChar ? 1 : 0);
    boolean evenParityBad = (evenSum & 0x01) == 1;

    boolean incrementOdd = false;
    boolean decrementOdd = false;
    boolean incrementEven = false;
    boolean decrementEven = false;

    if (outsideChar) {
      if (oddSum > 12) {
        decrementOdd = true;
      } else if (oddSum < 4) {
        incrementOdd = true;
      }
      if (evenSum > 12) {
        decrementEven = true;
      } else if (evenSum < 4) {
        incrementEven = true;
      }
    } else {
      if (oddSum > 11) {
        decrementOdd = true;
      } else if (oddSum < 5) {
        incrementOdd = true;
      }
      if (evenSum > 10) {
        decrementEven = true;
      } else if (evenSum < 4) {
        incrementEven = true;
      }
    }

    /*if (mismatch == 2) {
      if (!(oddParityBad && evenParityBad)) {
        throw ReaderException.getInstance();
      }
      decrementOdd = true;
      decrementEven = true;
    } else if (mismatch == -2) {
      if (!(oddParityBad && evenParityBad)) {
        throw ReaderException.getInstance();
      }
      incrementOdd = true;
      incrementEven = true;
    } else */if (mismatch == 1) {
      if (oddParityBad) {
        if (evenParityBad) {
          throw NotFoundException.getNotFoundInstance();
        }
        decrementOdd = true;
      } else {
        if (!evenParityBad) {
          throw NotFoundException.getNotFoundInstance();
        }
        decrementEven = true;
      }
    } else if (mismatch == -1) {
      if (oddParityBad) {
        if (evenParityBad) {
          throw NotFoundException.getNotFoundInstance();
        }
        incrementOdd = true;
      } else {
        if (!evenParityBad) {
          throw NotFoundException.getNotFoundInstance();
        }
        incrementEven = true;
      }
    } else if (mismatch == 0) {
      if (oddParityBad) {
        if (!evenParityBad) {
          throw NotFoundException.getNotFoundInstance();
        }
        // Both bad
        if (oddSum < evenSum) {
          incrementOdd = true;
          decrementEven = true;
        } else {
          decrementOdd = true;
          incrementEven = true;
        }
      } else {
        if (evenParityBad) {
          throw NotFoundException.getNotFoundInstance();
        }
        // Nothing to do!
      }
    } else {
      throw NotFoundException.getNotFoundInstance();
    }

    if (incrementOdd) {
      if (decrementOdd) {
        throw NotFoundException.getNotFoundInstance();
      }
      increment(getOddCounts(), getOddRoundingErrors());
    }
    if (decrementOdd) {
      decrement(getOddCounts(), getOddRoundingErrors());
    }
    if (incrementEven) {
      if (decrementEven) {
        throw NotFoundException.getNotFoundInstance();
      }
      increment(getEvenCounts(), getOddRoundingErrors());
    }
    if (decrementEven) {
      decrement(getEvenCounts(), getEvenRoundingErrors());
    }

  }

}
