// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// Original code is licensed as follows:
/*
 * 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.
 */

#include "xfa/fxbarcode/BC_UtilRSS.h"

#include <memory>

#include "core/fxcrt/include/fx_basic.h"
#include "xfa/fxbarcode/utils.h"

CBC_UtilRSS::CBC_UtilRSS() {}
CBC_UtilRSS::~CBC_UtilRSS() {}
CFX_Int32Array* CBC_UtilRSS::GetRssWidths(int32_t val,
                                          int32_t n,
                                          int32_t elements,
                                          int32_t maxWidth,
                                          FX_BOOL noNarrow) {
  std::unique_ptr<CFX_Int32Array> widths(new CFX_Int32Array);
  widths->SetSize(elements);
  int32_t bar;
  int32_t narrowMask = 0;
  for (bar = 0; bar < elements - 1; bar++) {
    narrowMask |= (1 << bar);
    int32_t elmWidth = 1;
    int32_t subVal;
    while (TRUE) {
      subVal = Combins(n - elmWidth - 1, elements - bar - 2);
      if (noNarrow && (narrowMask == 0) &&
          (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
        subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2);
      }
      if (elements - bar - 1 > 1) {
        int32_t lessVal = 0;
        for (int32_t mxwElement = n - elmWidth - (elements - bar - 2);
             mxwElement > maxWidth; mxwElement--) {
          lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3);
        }
        subVal -= lessVal * (elements - 1 - bar);
      } else if (n - elmWidth > maxWidth) {
        subVal--;
      }
      val -= subVal;
      if (val < 0) {
        break;
      }
      elmWidth++;
      narrowMask &= ~(1 << bar);
    }
    val += subVal;
    n -= elmWidth;
    (*widths)[bar] = elmWidth;
  }
  (*widths)[bar] = n;
  return widths.release();
}
int32_t CBC_UtilRSS::GetRSSvalue(CFX_Int32Array& widths,
                                 int32_t maxWidth,
                                 FX_BOOL noNarrow) {
  int32_t elements = widths.GetSize();
  int32_t n = 0;
  for (int32_t i = 0; i < elements; i++) {
    n += widths[i];
  }
  int32_t val = 0;
  int32_t narrowMask = 0;
  for (int32_t bar = 0; bar < elements - 1; bar++) {
    int32_t elmWidth;
    for (elmWidth = 1, narrowMask |= (1 << bar); elmWidth < widths[bar];
         elmWidth++, narrowMask &= ~(1 << bar)) {
      int32_t subVal = Combins(n - elmWidth - 1, elements - bar - 2);
      if (noNarrow && (narrowMask == 0) &&
          (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
        subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2);
      }
      if (elements - bar - 1 > 1) {
        int32_t lessVal = 0;
        for (int32_t mxwElement = n - elmWidth - (elements - bar - 2);
             mxwElement > maxWidth; mxwElement--) {
          lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3);
        }
        subVal -= lessVal * (elements - 1 - bar);
      } else if (n - elmWidth > maxWidth) {
        subVal--;
      }
      val += subVal;
    }
    n -= elmWidth;
  }
  return val;
}
int32_t CBC_UtilRSS::Combins(int32_t n, int32_t r) {
  int32_t maxDenom;
  int32_t minDenom;
  if (n - r > r) {
    minDenom = r;
    maxDenom = n - r;
  } else {
    minDenom = n - r;
    maxDenom = r;
  }
  int32_t val = 1;
  int32_t j = 1;
  for (int32_t i = n; i > maxDenom; i--) {
    val *= i;
    if (j <= minDenom) {
      val /= j;
      j++;
    }
  }
  while (j <= minDenom) {
    val /= j;
    j++;
  }
  return val;
}
CFX_Int32Array* CBC_UtilRSS::Elements(CFX_Int32Array& eDist,
                                      int32_t N,
                                      int32_t K) {
  CFX_Int32Array* widths = new CFX_Int32Array;
  widths->SetSize(eDist.GetSize() + 2);
  int32_t twoK = K << 1;
  (*widths)[0] = 1;
  int32_t i;
  int32_t minEven = 10;
  int32_t barSum = 1;
  for (i = 1; i < twoK - 2; i += 2) {
    (*widths)[i] = eDist[i - 1] - (*widths)[i - 1];
    (*widths)[i + 1] = eDist[i] - (*widths)[i];
    barSum += (*widths)[i] + (*widths)[i + 1];
    if ((*widths)[i] < minEven) {
      minEven = (*widths)[i];
    }
  }
  (*widths)[twoK - 1] = N - barSum;
  if ((*widths)[twoK - 1] < minEven) {
    minEven = (*widths)[twoK - 1];
  }
  if (minEven > 1) {
    for (i = 0; i < twoK; i += 2) {
      (*widths)[i] += minEven - 1;
      (*widths)[i + 1] -= minEven - 1;
    }
  }
  return widths;
}
