/***************************************************************************
                          babylon_bgl.cpp  -  description
	This library is based on the work of Raul Fernandes and Karl Grill
	on dictconv

                             -------------------
    begin                : February 2009
    copyright            : (c) 2007 by Iven Wold - 526f6c616e642053756368616e
    email                : hour.glass2@yahoo.com
    license              : GPL v 2.0
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This file is part of QTrans.                                          *
 *                                                                         *
 *   QTrans is free software; you can redistribute it and/or modify        *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; version 2 of the License.               *
 *                                                                         *
 *   QTrans is distributed in the hope that it will be useful,             *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with QTrans. If not, see <http://www.gnu.org/licenses/> or      *
 *   write to the Free Software Foundation, Inc.,                          *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.         *
 *                                                                         *
 ***************************************************************************/

#include <QMessageBox>
//#include <KLocale>    //oooo
#include <KLocalizedString> //xxxx
#include <QDebug>	//ooo
#include <QUrl>		//ooo
#include <QDir>		//ooo
#include <QTextCodec>	//ooo

#include <iostream>	//ooo
#include <stdlib.h>	//ooo
#include <zlib.h>	//ooo
#include <stdio.h>	//ooo

#include "babylon_bgl.h"
#include "utils.h"

extern "C" {
   bool readBlock( bgl_block &block );
}

Babylon_bgl::Babylon_bgl(QString filename, QString strIndexDir, QString word, bool enableAlternates, int encodingExpression_id)
{
	//m_filename = filename.toAscii().data();  //oooo
    m_filename = filename.toLatin1().data();    //xxxx
	b_enableAlternates = enableAlternates;
	i_encodingExpression_id = encodingExpression_id;
	//m_word1 = word.toAscii().data();
	mq_word = word;
	//m_word1 = word.toAscii().data(); //oooo
    m_word1 = word.toLatin1().data();   //xxxx
	m_word = std::wstring(m_word1.begin(), m_word1.end());

	//ba = filename.toStdString().c_str();

	//ba = QByteArray(filename.toAscii().data());
	//ba = filename.toAscii();
	//ba = "/home/gons/.qtrans/index";
	//ba = filename.toUtf8();
	//ba = filename.toAscii(); //oooo
    ba = filename.toLatin1();   //xxxx
	 //h_filename = filename.toUtf8().toHex().data();
	//h_filename = ba.toHex().data();
	m_qstrIndexDir = strIndexDir;
	//m_strIndexDir = strIndexDir.toAscii().data();    //oooo
    m_strIndexDir = strIndexDir.toLatin1().data();  //xxxx
}

Babylon_bgl::~Babylon_bgl()
{
}

QString Babylon_bgl::printMessage()
{
	//QMessageBox::about(this, tr("About Diagram Scene"), tr("printMessage(: 1"));
	//QMessageBox::about(i18n("About Menu"), QString("%1").arg("printMessage(: 1"));

	return "Babylon BGL <---> !!!";
}


bool Babylon_bgl::open()
{
	FILE *f;
	unsigned char buf[6];
	int i;

	f = fopen( m_filename.c_str(), "r" );
	if( f == NULL )
		return false;

	i = fread( buf, 1, 6, f );

	/* First four bytes: BGL signature 0x12340001 or 0x12340002 (big-endian) */
	if( i < 6 || memcmp( buf, "\x12\x34\x00", 3 ) || buf[3] == 0 || buf[3] > 2 )
		return false;

	/* Calculate position of gz header */

	i = buf[4] << 8 | buf[5];

	if( i < 6 )
		return false;

	if( fseek( f, i, SEEK_SET ) ) /* can't seek - emulate */
	for(int j=0;j < i - 6;j++) fgetc( f );

	if( ferror( f ) || feof( f ) )
		return false;

	/* we need to flush the file because otherwise some nfs mounts don't seem
	* to properly update the file position for the following reopen */

	fflush( f );

	file = gzdopen( dup( fileno( f ) ), "r" );
	if( file == NULL )
		return false;

	fclose( f );

	return true;

/*	QFile file(m_filename);
	if (!file.open(QIODevice::ReadOnly)) {
		return false;
	}

	return true;
*/
}

/*void alloc(unsigned char **data) {
    *data = (unsigned char *) malloc( 20 );
    if ( *data ) memset( *data, 0, 20 );
}*/

/*unsigned char * alloc() {
    unsigned char *data = (unsigned char *) malloc( 20 );

    if ( data ) memset( data, 0, 20 );

    return data;
}*/


bool Babylon_bgl::readBlock( bgl_block &block )
{
	if( gzeof( file ) || file == NULL ) {
		return false;
	}

	block.length = bgl_readnum( 1 );
	block.type = block.length & 0xf;

	if( block.type == 4 ) {
		return false; // end of file marker
	}
	block.length >>= 4;
	block.length = block.length < 4 ? bgl_readnum( block.length + 1 ) : block.length - 4 ;

	if( block.length ) {
		//block.data = (char *)malloc( block.length );
		block.data = (unsigned char *)malloc( block.length );	//ooo
        //block.data = static_cast<unsigned char *>(malloc( block.length ));	//ooo
        //block.data = static_cast<unsigned char *>(malloc(4*sizeof(*block.data)));	//ooo
        //if (block.data==NULL) exit (1);
        if (block.data==NULL) {
          std::cerr << "Couldn't allocate memory for a block.data" << std::endl;
          abort();
        }
        memset(block.data, 0, block.length);
        //char *pBuffer = new char[1024];
        //block.data = new unsigned char[1024];    //ooo
        //memset( block.data, 0, block.length );  //ooo
		gzread( file, block.data, block.length );
        //gzread( file, *block.data, block.length );  //ooo
        //free(block.data);
	}

	return true;
}


unsigned int Babylon_bgl::bgl_readnum( int bytes )
{
	unsigned char buf[4];
	unsigned val = 0;

	if ( bytes < 1 || bytes > 4 ) return (0);

	gzread( file, buf, bytes );
	for(int i=0;i<bytes;i++) val= (val << 8) | buf[i];
	return val;
}


bool Babylon_bgl::read()
{
	if( file == NULL ) return false;

	bgl_block block;
	uint pos;
	uint type;
	std::string headword;
	std::string definition;
    
    bool isUtf8File = false;

	m_numEntries = 0;
	while( readBlock( block ) ) {

		headword.clear();
		definition.clear();
		switch( block.type ) {
			case 0:
				switch( block.data[0] ) {
					case 8:
						type = (uint)block.data[2];

						if( type > 64 ) type -= 65;
						m_defaultCharset = bgl_charset[type];
						break;
					default:
						break;
				}
				break;
			case 1:
			case 10:
				// Only count entries
				m_numEntries++;
				break;
			case 3:
				pos = 2;
				switch( block.data[1] ) {
					case 1:
						headword.reserve( block.length - 2 );
						for(uint a=0;a<block.length-2;a++) headword += block.data[pos++];
						m_title = headword;
						break;
					case 2:
						headword.reserve( block.length - 2 );
						for(uint a=0;a<block.length-2;a++) headword += block.data[pos++];
						m_author = headword;
						break;
					case 3:
						headword.reserve( block.length - 2 );
						for(uint a=0;a<block.length-2;a++) headword += block.data[pos++];
						m_email = headword;
						break;
					case 4:
						headword.reserve( block.length - 2 );
						for(uint a=0;a<block.length-2;a++) headword += block.data[pos++];
						m_copyright = headword;
						break;
					case 7:
						headword = bgl_language[block.data[5]];
						m_sourceLang = headword;
						break;
					case 8:
						headword = bgl_language[block.data[5]];
						m_targetLang = headword;
						break;
					case 9:
						headword.reserve( block.length - 2 );
						for(uint a=0;a<block.length-2;a++) headword += block.data[pos++];   //ooo
                        /*for(unsigned int a=0;a<block.length-2;a++) {    //xxx
                            if (block.data[pos] == '\r') {
                            } else if (block.data[pos] == '\n') {
                                headword += "<br>";
                            } else {
                                headword += block.data[pos];
                            }
                                pos++;
                        }*/
						m_description = headword;
						break;
                    /*case 11:
                        icon.resize( block.length - 2 );
                        memcpy( &icon.front(), &(block.data[ 2 ]), icon.size() );
                        break;*/    //xxx
                    /*case 17:
                        if ( block.length >= 5 && (unsigned char) block.data[ 4 ] == 0x80 )
                            isUtf8File = true;
                        break;*/    //xxx
					case 26:
						type = (uint)block.data[2];
						if( type > 64 ) type -= 65;
                        /*if ( type >= 14 )   //xxx
                          type = 0; //xxx
                        if (m_sourceCharset.empty())    //xxx  */
                            m_sourceCharset = bgl_charset[type];
						break;
					case 27:
						type = (uint)block.data[2];
						if( type > 64 ) type -= 65;
                        /*if ( type >= 14 )   //xxx
                            type = 0;   //xxx
                        if (m_targetCharset.empty())    //xxx */
                            m_targetCharset = bgl_charset[type];
						break;
					default:
						break;
				}
				break;
			default:
				;
		}

		if( block.length ) free( block.data );

	}
	gzseek( file, 0, SEEK_SET );
    
  /*if ( isUtf8File )
  {
    //fprintf( stderr, "%s: utf8 file.\n", m_title.c_str() );
    m_defaultCharset = "UTF-8";
    m_sourceCharset = "UTF-8";
    m_targetCharset = "UTF-8";
  }*/   //xxx

	//convertToUtf8( m_title, DEFAULT_CHARSET );
	//convertToUtf8( m_author, DEFAULT_CHARSET );
	//convertToUtf8( m_email, DEFAULT_CHARSET );
	//convertToUtf8( m_copyright, DEFAULT_CHARSET );
	//convertToUtf8( m_description, DEFAULT_CHARSET );

    //printf("Default charset: %s\nSource Charset: %s\nTargetCharset: %s\n", m_defaultCharset.c_str(), m_sourceCharset.c_str(), m_targetCharset.c_str());

	return true;
}


bgl_entry Babylon_bgl::readEntry()
{ 
	bgl_entry entry;

	if( file == NULL )
	{
		entry.headword = L"";
		return entry;
	}

	bgl_block block;
	//uint len, pos;
	unsigned int len, pos;			//ooo
	std::wstring headword;
	std::wstring definition;
	std::wstring definition_stack = L"";	//ooo
	std::wstring definition_origin = L"";	//ooo
	std::wstring temp;
	std::vector<std::wstring> alternates;
	std::wstring alternate;
	//int j = -1;	//ooo

	const std::wstring headword1 = L"Where was Acheulian";
	const std::wstring toFind = L"être"; //L"Acheulian";
	const std::wstring toFind_x2 = L"1,500,000";
	std::wstring transcription = L"";
	//std::wstring filename = L"";
	std::string filename = "";
	std::string filename_2 = "";	//ooo
	std::wstring::size_type n = 0;
	QCryptographicHash hash( QCryptographicHash::Md5 );
	std::string hash_str = "";
	unsigned char const * data;
    //char const * data;
	//size_t size; //o
    std::size_t size = 0;      //x
    
	std::vector < unsigned char > compressedData( compressBound( size ) );
    
	unsigned long compressedSize;
	//char const *indexFile = "myFile";
	//File::Class idx( indexFile, "w" );
	//FILE *fopen( indexFile, "w" );
	FILE *fp;
	QUrl url;
	std::string url_str;
	QDir dir;			//ooo
	QDir hashDir;			//ooo
	bool dirWasCreated = false;	//ooo
	int j = 0;			//ooo
	//std::string temp_head = "";	//ooo
	
	QString wordExpressionString;
	QByteArray encodedWordExpressinString;
	QTextCodec *languageCodec;
	
	hash.reset();					//ooo
	hash.addData( ba );				//ooo
	hash_str = hash.result().toHex().data();	//ooo
	
	//QString str_ = "/home/gons/.qtrans/index/" + hash.result().toHex();	//ooo
	QString strHashDir = m_qstrIndexDir + "/" + hash.result().toHex();	//ooo

	//dir = QDir("/home/gons/.qtrans/index/");	//ooo
	dir = QDir(m_qstrIndexDir);	//ooo
	//dir_2 = QDir(str_);				//ooo
	hashDir = QDir(strHashDir);			//ooo
				
	if (!hashDir.exists()) {			//ooo
		dir.mkpath( hash.result().toHex() );
		dirWasCreated = true;
	}
	
	languageCodec = QTextCodec::codecForName(Codec[i_encodingExpression_id].toLatin1());


	while( readBlock( block ) )
	{
		std::string temp_head = "";	//ooo
		QString qs_head = "";		//ooo

		switch( block.type )
		{
			//case 1:
			case 2:

				pos = 0;

				len = (unsigned char)block.data[pos++];

				//std::string filename( block.data+pos, len );

				/*for ( unsigned int i = (pos+3); i < (pos+3+length); i++) {
					 transcription += block.data[i];
				}*/
				

				for ( unsigned int i = pos; i < pos + len; i++) {

					 filename += block.data[i];
				}

				pos += len;

				/*unsigned char const * data = &block.data[pos];
				size_t size = block.length - pos;

				std::vector< unsigned char > compressedData( compressBound( size ) );

				unsigned long compressedSize = compressedData.size();*/

				data = &block.data[pos];
				size = block.length - pos;
                
				//compressedData.size() = compressBound(size);

				compressedSize = compressedData.size();

				if (dirWasCreated) {	//ooo
					//filename_2 = "/home/gons/.qtrans/index/" + hash_str + "/" + filename;
					 //filename_2 = std::string(m_qstrIndexDir.toAscii().data()) + "/" + hash_str + "/" + filename;    //oooo
                    filename_2 = std::string(m_qstrIndexDir.toLatin1().data()) + "/" + hash_str + "/" + filename;   //xxxx
					//filename_2 = m_strIndexDir + "/" + hash_str + "/" + filename;
					
					/*filename_2 = m_strIndexDir;
					filename_2 += "/";
					filename_2 += hash_str;
					filename_2 += "/";
					filename_2 += filename;
					*/
					fp = fopen(filename_2.c_str(), "w");
					fwrite(&block.data[pos], 1, size, fp);
					fclose(fp);
				}
				
				//filename = L"";
				filename = "";

				/*if (filename == "D437C11D.bmp") {

				}*/

				break;
			case 1:
			case 10:

				alternate.clear();
				headword.clear();
				definition.clear();
				temp.clear();
				pos = 0;

				definition_origin = L"";		//ooo ""

				// Headword
				len = 0;
				len = (unsigned char)block.data[pos++];

				headword.reserve( len );
				//for(uint a = 0; a < len; a++) headword += block.data[pos++];
				for (uint a = 0; a < len; a++) {
					
					/*if ( block.data[pos] == 232 ) {
						//headword += 269;
						headword += 0xC4;
						headword += 0x8D;
						//headword += 196;
						//headword += 141;
						pos++;
					} else {*/
						headword += (unsigned char)block.data[pos++];	//ooo
// 					/*}*/
				}
				//convertToUtf8( headword, SOURCE_CHARSET );

				//j = headword.find("black");
				//j = headword.find(m_word);
				//if ( j != std::wstring::npos ) continue;
				
				if ( !b_enableAlternates ) {
				  
					//std::copy(headword.begin(), headword.end(), std::back_inserter(temp_head));	//ooo
					   //j = temp_head.find(m_word1);
					   //if ( j < 0 ) continue;
					//qs_head = temp_head.c_str();
					
					//qs_head = QString::fromWCharArray(entry.headword.data(), int(entry.headword.size()));		//ooo
					qs_head = QString::fromWCharArray(headword.data(), int(headword.size()));			//ooo
					
					if ( i_encodingExpression_id != 0 ) {								//ooo
					  
						//qs_head = QString::fromWCharArray(headword.data(), int(headword.size()));		//ooo
						encodedWordExpressinString = qs_head.toLatin1();
						wordExpressionString = languageCodec->toUnicode(encodedWordExpressinString);
						
						if (!wordExpressionString.contains(mq_word, Qt::CaseInsensitive)) continue;
						
					} else {
					  
						if (!qs_head.contains(mq_word, Qt::CaseInsensitive)) continue;
						
					}
					
					//if (!qs_head.contains(mq_word, Qt::CaseInsensitive)) continue;
					//if (!wordExpressionString.contains(mq_word, Qt::CaseInsensitive)) continue;
				}

				// Definition
				len = 0;
				len = (unsigned char)block.data[pos++] << 8;
				//pos++;						//ooo
				//len = (unsigned char)block.data[pos++];		//ooo

				//len <<= 8;					//ooo

				len |= (unsigned char)block.data[pos++];
				definition.reserve( len );

				for (uint a = 0; a < len; a++) {

					if ( (unsigned char)block.data[pos] == 0x0a ) {		//LF: LineFeed

						definition += '\n';
						pos++;

					} else if ( (unsigned char)block.data[pos] == 0x06 ) {

						pos += 2;
						a++;

					} else if ( (unsigned char)block.data[pos] >= 0x40 && (unsigned char)block.data[pos + 1 ] == 0x18 &&
							len - a >= 2 ) {

						// B344
						unsigned length = (unsigned char)block.data[ pos ] - 0x3F;

						pos += length + 2;
						a += length + 1;

					} else if ( /*(unsigned char)block.data[pos-1] == 0x14 &&*/ (unsigned char)block.data[pos] == 0x18) {

						// definition = def + head

						// length of the explanation string	(Ita->Eng)
						unsigned int length = (unsigned char)block.data[ pos + 1 ];

						headword = L"";

						for ( unsigned int i = (pos+2); i < (pos+2+length); i++) {
							headword += block.data[i];
						}

						pos += length + 2;
						a += length + 1;

					} /*else if ( (unsigned char)block.data[pos-4] == 0x02 && (unsigned char)block.data[pos-2] == 0x06 && (unsigned char)block.data[pos] == 0x18 ) {

						//replace headword through headword explanation which is placed at the end of definition
						// Ab$3$ <- Ab...

						// length of the explanation string
						unsigned int length = (unsigned char)block.data[ pos + 1 ];

						headword = L"";

						for ( unsigned int i = (pos+2); i < (pos+2+length); i++) {
							headword += block.data[i];
						}

						pos += length + 2;
						a += length + 1;

					} else if ( (unsigned char)block.data[pos-3] == 0x14 && (unsigned char)block.data[pos-2] == 0x06 && (unsigned char)block.data[pos] == 0x18 ) {

						//replace headword through headword explanation which is placed at the begining of definition

						// length of the explanation string
						unsigned int length = (unsigned char)block.data[ pos + 1 ];

						headword = L"";

						for ( unsigned int i = (pos+2); i < (pos+2+length); i++) {
							headword += block.data[i];
						}

						pos += length + 2;
						a += length + 1;

					} else if ( (unsigned char)block.data[pos-3] == 0x14 && (unsigned char)block.data[pos-2] == 0x02 && (unsigned char)block.data[pos] == 0x18 ) {

						//replace headword through headword explanation which is placed at the end of definition

						// length of the explanation string
						unsigned int length = (unsigned char)block.data[ pos + 1 ];

						headword = L"";

						for ( unsigned int i = (pos+2); i < (pos+2+length); i++) {
							headword += block.data[i];
						}

						pos += length + 2;
						a += length + 1;*/

					/*} else if ( ((unsigned char)block.data[pos] >= 0x41 && (unsigned char)block.data[pos] <= 0x5A &&
							(unsigned char)block.data[pos+1] == 0x10)
							|| ((unsigned char)block.data[pos] >= 0x41 && (unsigned char)block.data[pos] <= 0x5A &&
							(unsigned char)block.data[pos+1] >= 0x41 && (unsigned char)block.data[pos+1] <= 0x5A &&
							(unsigned char)block.data[pos+2] == 0x10) ) {

						// heb->eng
						pos += len - a;
						//a += len - a;
						break;*/

					/*}*/ else if ( (unsigned char)block.data[pos] >= 0x41 && (unsigned char)block.data[pos] <= 0x5A &&
							(unsigned char)block.data[pos+1] == 0x10 ) {

						// heb->eng
						pos += len - a;
						a += len - a;
						break;

					} else if ( (unsigned char)block.data[pos] == 0x1A && (unsigned char)block.data[pos] >= 0x03 ) {

						// heb->eng
						pos += len - a;
						a += len - a;
						break;

					} else if ( (unsigned char)block.data[pos] == 0x50 && (unsigned char)block.data[pos + 1 ] == 0x1B &&
							len - a - 1 >= 2 ) {

						unsigned int length = (unsigned char)block.data[pos + 2 ];

						for ( unsigned int i = (pos+3); i < (pos+3+length); i++) {
							 transcription += block.data[i];
						}

						definition = L"[" + std::wstring( L"<span class=\"bgltrn\">" ) + transcription + L"</span>" + L"] " + definition;
						
						/*definition_stack = L"[";
						definition_stack += L"<span class=\"bgltrn\">";
						definition_stack += transcription;
						definition_stack += L"</span>";
						definition_stack += L"]";
						definition.insert(0,definition_stack);
						*/
						
						/*definition.insert(0,L"]");
						definition.insert(0,L"</span>");
						definition.insert(0,transcription);
						definition.insert(0,L"<span class=\"bgltrn\">");
						definition.insert(0,L"[");
						*/
						pos += length + 3;
						a += length + 2;

					} else if ( (unsigned char)block.data[pos] == 0x60 && (unsigned char)block.data[pos + 1 ] == 0x1B &&
							len - a - 1 >= 2 ) {

						unsigned int length = (unsigned char)block.data[pos + 2 ];

						length <<= 8;
						length += (unsigned char)block.data[pos + 3 ];

						for ( unsigned int i = (pos+4); i < (pos+4+length); i++) {
							 transcription += block.data[i];
						}

						definition = L"[" + std::wstring( L"<span class=\"bgltrn\">" ) + transcription + L"</span>" + L"] " + definition;

						/*definition_stack = L"[";
						definition_stack += L"<span class=\"bgltrn\">";
						definition_stack += transcription;
						definition_stack += L"</span>";
						definition_stack += L"]";
						//definition.insert(0,definition_stack);
						
						definition = definition_stack + definition;
						*/
						
						/*definition.insert(0,L"]");
						definition.insert(0,L"</span>");
						definition.insert(0,transcription);
						definition.insert(0,L"<span class=\"bgltrn\">");
						definition.insert(0,L"[");
						*/
						pos += length + 4;
						a += length + 3;

					} else if ( (unsigned char)block.data[pos] == 0x1E ) {

						
						//QCryptographicHash *crypt = new QCryptographicHash(QCryptographicHash::Md5); 

						//QByteArray string = x.toStdString().c_str();
						//crypt->addData(ba);

						//hash.reset();
						//hash.addData( ba );

						//hash_str = hash.result().toHex().data();

						/*++pos;

						while ( (unsigned char)block.data[pos] != 0x1F ) {
							filename += block.data[pos++];
						}*/

						url.setScheme( "bres" );
						//url.setHost( QString::fromUtf8( getId().c_str() ) );
						url.setHost( QString::fromUtf8( "/home/gons/.qtrans/index" ) );

						//url.setPath( QString::fromUtf8( filename.c_str() ) );
						//url.setPath( QString::fromUtf8( filename.c_str() ) );

						url_str = url.toEncoded().data();

						//ba = hash(ba, QCryptographicHash::Md5);

						//definition += L"bres:///usr/share/trans/babylon/Concise_Oxford_English_Diction.BGL/";
						//definition += std::wstring( L"bres://" ) + std::wstring(h_filename.begin(), h_filename.end()) + L"/";
						//definition += std::wstring( L"bres://" ) + std::wstring(hash_str.begin(), hash_str.end()) + L"/";
						//definition += std::wstring(url_str.begin(), url_str.end()) + L"/";
						//definition += std::wstring( L"file://" ) + std::wstring( L"/home/gons/.qtrans/index" ) + L"/";
						//definition += std::wstring( L"file://" ) + std::wstring( L"/home/gons/.qtrans/index/" ) + std::wstring(hash_str.begin(), hash_str.end()) + L"/";
						//definition += std::wstring( L"file://" ) + std::wstring((std::string(m_qstrIndexDir.toAscii().data())).begin(), (std::string(m_qstrIndexDir.toAscii().data())).end()) + L"/" + std::wstring(hash_str.begin(), hash_str.end()) + L"/";
						//definition += std::wstring( L"file://" ) + std::wstring(std::string(m_qstrIndexDir)) + L"/" + std::wstring(hash_str.begin(), hash_str.end()) + L"/";
						 //definition += std::wstring( L"file://" ) + std::wstring(m_strIndexDir.begin(), m_strIndexDir.end()) + L"/" + std::wstring(hash_str.begin(), hash_str.end()) + L"/";
						//definition += std::wstring( L"bres://" ) + std::wstring(crypt->result().data().begin(), crypt->result().data().end()) + L"/";
						
						definition += L"file://";
						definition += std::wstring(m_strIndexDir.begin(), m_strIndexDir.end());
						definition += L"/";
						definition += std::wstring(hash_str.begin(), hash_str.end());
						definition += L"/";
						
						++pos;

					} else if ( (unsigned char)block.data[pos] == 0x1F ) {

						//definition += std::wstring( L"\" alt=\"Grafik" );
						//pos += 2;
						++pos;

					} else if ( (unsigned char)block.data[pos] < 0x20 ) {	//SP: Space

						if ( a <= /*<*/ len - 3 && block.data[pos] == 0x14 && block.data[pos+1] == 0x02 ) {

							//definition = partOfSpeech[(unsigned char)block.data[pos+2] - 0x30] + " " + definition;
							definition = partOfSpeech[(unsigned char)block.data[pos+2] - 0x30] + L" " + definition;	//ooo
						//}


							pos += 3;	//ooo
							a += 2;		//ooo

						//pos += len - a;
						//break;

						}	//ooo

						else if (block.data[pos] == 0x14) {
							pos++;
						} else {				//ooo
							definition += block.data[pos++];   //o
                            //definition += (unsigned char)block.data[pos++];    //x
						}

					} else {

						if (block.data[pos] == 0x96 && ( (block.data[pos+1] >= 0x30 && block.data[pos+1] <= 0x39) ||
							(block.data[pos+1] >= 0x41 && block.data[pos+1] <= 0x5A) ||
							(block.data[pos+1] >= 0x61 && block.data[pos+1] <= 0x7A))) {	//ooo but eng->jpn problem

							definition += 0x2D;		// "-"
							pos++;
						} else {

							definition += block.data[pos++];   //o
                            //definition += (unsigned char)block.data[pos++]; //x

						}

						//definition += block.data[pos++];
					}

					//int place = definition.find("black");

					//if (definition.find("black") != -1) {
					//if (place >= 0) {
					//}

				}
				//convertToUtf8( definition, TARGET_CHARSET );

				// Alternate forms
				while ( pos != block.length ) {
					len = (unsigned char)block.data[pos++];
					alternate.reserve( len );
					for (uint a = 0; a < len; a++) alternate += block.data[pos++];
					//convertToUtf8( alternate, SOURCE_CHARSET );

					alternates.push_back( alternate );
					alternate.clear();
				}

				entry.headword = headword;
				entry.definition = definition;

				/*if (definition_stack != L"") {	//ooo
					entry.definition = definition_stack;
				} else {
					entry.definition = definition;
				}*/

				//if ( (n = headword.find(L"")) != std::wstring::npos) {
				/*if ( (n = definition_stack.find(L"")) != std::wstring::npos) {
					entry.definition = definition;
				} else {
					entry.definition = definition_stack;
				}*/

				//if ( (n = definition_stack.find(L"")) == std::wstring::npos) {
				/*if ( definition_stack.empty()) {

					entry.definition = definition_stack;
				} else {

					entry.definition = definition;
				}*/

				entry.alternates = alternates;

				return entry;

				break;
			default:
				;
		}

		if( block.length ) free( block.data );
	}

	entry.headword = L"";

	return entry;
}


//#include "babylon_bgl.moc"
