// 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 "barcode.h"
#include "BC_UtilRSS.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)
{
    CFX_Int32Array *iTemp =  FX_NEW CFX_Int32Array;
    iTemp->SetSize(elements);
    CBC_AutoPtr<CFX_Int32Array > widths(iTemp);
    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 = FX_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;
}
