/*
 * Copyright (C) 2007 Pleyo.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Pleyo nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY PLEYO AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL PLEYO OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "kjs/wk_config.h"
#include "BTTextCodec.h"
#include "PlatformString.h"
#include "DeprecatedString.h"
#include "CString.h"

#include "../../general/utf8_util.h"

namespace WebCore {

void BTTextCodec::registerEncodingNames(EncodingNameRegistrar registrar)
{
    registrar("UTF-8", "UTF-8");
}

static std::auto_ptr<TextCodec> newBTTextCodec(const TextEncoding& encoding, const void*)
{
    return std::auto_ptr<TextCodec>(new BTTextCodec(encoding));
}

void BTTextCodec::registerCodecs(TextCodecRegistrar registrar)
{
    registrar("UTF-8", newBTTextCodec, 0);
}

BTTextCodec::BTTextCodec(const TextEncoding& encoding)
    : m_encoding(encoding), m_haveBufferedByte(false)
{
}


BTTextCodec::~BTTextCodec()
{
    m_encoding = 0;
}

String BTTextCodec::decode(const char* bytes, size_t length, bool flush)
{
    if (!length)
        return String();

    const unsigned char* utf8 = (const unsigned char *) bytes;
    Vector<UChar> uc(length);
    size_t j = 0;
    for (size_t i = 0; i < length; i++) {
        unsigned char b0 = utf8[i];

        if ( UTF8_HAS_1_BYTE(utf8[i])) 
            uc[j++] = utf8[i];
        else if (UTF8_HAS_2_BYTES(b0, i, length)) {
            unsigned char b1 = utf8[++i];

            if (UTF8_IS_LATIN1(b0, b1)) {
                uc[j++] = UTF8_LATIN1_TO_UCHAR(b0, b1);
#ifdef DEBUG
                printf("*** uc[%u] = 0x%04X, b0 = 0x%X, b1 = 0x%X\n", j, uc[j-1], b0, b1);
#endif
            }
            else  
                uc[j++] = '?'; // unrecognized char
        }
        else if (UTF8_HAS_3_BYTES(b0, i, length)) { 
            uc[j++] = '?'; // unrecognized char
            i += 1;
        }
        else if (UTF8_HAS_4_BYTES(b0, i, length)) { 
            uc[j++] = '?'; // unrecognized char
            i += 2;
        }
        else if (UTF8_HAS_5_BYTES(b0, i, length)) { 
            uc[j++] = '?'; // unrecognized char
            i += 3;
        }
        else if (UTF8_HAS_6_BYTES(b0, i, length)) { 
            uc[j++] = '?'; // unrecognized char
            i += 4;
        }
        // assertion: else, ignore this (invalid) char 
    }

    uc.resize(j);
    return String::adopt(uc);
}

CString BTTextCodec::encode(const UChar* characters, size_t length, bool allowEntities)
{
    char* bytes;
    CString string = CString::newUninitialized(length * 2, bytes);
    return string;
}


} // namespace WebCore
