//
// Okzoniom::RPG
// Copyright (C) 2010 - 2013
// Okzoniom::RPG Development Team
//  - Louis SCHNELLBACH
//
// This file is part of the Okzoniom::RPG Game.
//

#include <iostream>
#include <cstring>
#include <sstream>
#include "Utils.h"
#include "Log.h"
#include "Lua.h"

std::wstring okz::wide(const std::string& s)
{
    std::wstring wideString;
    uint32_t ascii = 0;
    uint32_t nAscii = 0;
    uint8_t byte[4] = {0,0,0,0};
    uint8_t ctrl[3] = {0xF0, 0xE0, 0xC0};
    uint8_t mask[3] = {0x7, 0xF, 0x1F};
    uint8_t nbByte = 0;
    for(uint32_t i = 0; i < s.size(); ++i)
    {
        //Get each byte for the code
        ascii = s[i];
        // BYTE 0 --> 3
        for(int j = 0; j < 4; ++j)
            byte[j] = ascii >> ((3-j)*8);

        //We have still some byte to treat
        if(nbByte > 0)
        {
            --nbByte;
            nAscii = (nAscii << 6) | (byte[3-nbByte] & 0x3F);
            //Add new char !
            if(nbByte == 0)
                wideString.push_back(nAscii);
        }
        else
        {
            //Ok, new char
            //Simple test to know if multi byte:
            if((char)ascii > 0)
            {
                //1-Byte ASCII, so treated here, and then next char !
                wideString.push_back(ascii);
            }
            else
            {
                //So only need to check the first 3 bytes
                for(int j = 0; j < 3; ++j)
                    if(nbByte > 0)
                        break;
                    else nbByte = byte[2-j] & ctrl[2-j];
                //Get the correct byte number
                nbByte = (nbByte == 0xF0 ? 3 : nbByte == 0xE0 ? 2 : 1);
                nAscii = 0 | ascii & mask[3-nbByte];
            }
        }
    }
    return wideString;
}