// 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 2006-2007 Jeremias Maerki.
 *
 * 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_Dimension.h"
#include "../BC_UtilCodingConvert.h"
#include "../common/BC_CommonBitMatrix.h"
#include "BC_Encoder.h"
#include "BC_SymbolShapeHint.h"
#include "BC_SymbolInfo.h"
#include "BC_EncoderContext.h"
CBC_EncoderContext::CBC_EncoderContext(const CFX_WideString msg, CFX_WideString ecLevel, int32_t &e)
{
    CFX_ByteString dststr;
    CBC_UtilCodingConvert::UnicodeToUTF8(msg, dststr);
    CFX_WideString sb;
    int32_t c = dststr.GetLength();
    for (int32_t i = 0; i < c; i++) {
        FX_WCHAR ch =  (FX_WCHAR)(dststr.GetAt(i) & 0xff);
        if (ch == '?' && dststr.GetAt(i) != '?') {
            e = BCExceptionCharactersOutsideISO88591Encoding;
        }
        sb += ch;
    }
    m_msg = sb;
    m_shape = FORCE_NONE;
    m_newEncoding = -1;
    m_pos = 0;
    m_symbolInfo = NULL;
    m_skipAtEnd = 0;
    m_maxSize = NULL;
    m_minSize = NULL;
}
CBC_EncoderContext::~CBC_EncoderContext()
{
}
void CBC_EncoderContext::setSymbolShape(SymbolShapeHint shape)
{
    m_shape = shape;
}
void CBC_EncoderContext::setSizeConstraints(CBC_Dimension* minSize, CBC_Dimension* maxSize)
{
    m_maxSize = maxSize;
    m_minSize = minSize;
}
CFX_WideString CBC_EncoderContext::getMessage()
{
    return m_msg;
}
void CBC_EncoderContext::setSkipAtEnd(int32_t count)
{
    m_skipAtEnd = count;
}
FX_WCHAR CBC_EncoderContext::getCurrentChar()
{
    return m_msg.GetAt(m_pos);
}
FX_WCHAR CBC_EncoderContext::getCurrent()
{
    return m_msg.GetAt(m_pos);
}
void CBC_EncoderContext::writeCodewords(CFX_WideString codewords)
{
    m_codewords += codewords;
}
void CBC_EncoderContext::writeCodeword(FX_WCHAR codeword)
{
    m_codewords += codeword;
}
int32_t CBC_EncoderContext::getCodewordCount()
{
    return m_codewords.GetLength();
}
void CBC_EncoderContext::signalEncoderChange(int32_t encoding)
{
    m_newEncoding = encoding;
}
void CBC_EncoderContext::resetEncoderSignal()
{
    m_newEncoding = -1;
}
FX_BOOL CBC_EncoderContext::hasMoreCharacters()
{
    return m_pos < getTotalMessageCharCount();
}
int32_t CBC_EncoderContext::getRemainingCharacters()
{
    return getTotalMessageCharCount() - m_pos;
}
void CBC_EncoderContext::updateSymbolInfo(int32_t &e)
{
    updateSymbolInfo(getCodewordCount(), e);
}
void CBC_EncoderContext::updateSymbolInfo(int32_t len, int32_t &e)
{
    if (m_symbolInfo == NULL || len > m_symbolInfo->m_dataCapacity) {
        m_symbolInfo = CBC_SymbolInfo::lookup(len, m_shape, m_minSize, m_maxSize, true, e);
        BC_EXCEPTION_CHECK_ReturnVoid(e);
    }
}
void CBC_EncoderContext::resetSymbolInfo()
{
    m_shape = FORCE_NONE;
}
int32_t CBC_EncoderContext::getTotalMessageCharCount()
{
    return m_msg.GetLength() - m_skipAtEnd;
}
