

#include "LZArchive.h"
#include <include/hssUtility.h>

#include <string.h>



LZArchive::LZArchive() {

    m_numitems = 0;
    m_totallength = 0;
    m_open = false;
}

LZArchive::~LZArchive() {

    close();
}


bool LZArchive::open(const TCHAR *name) {

    TCHAR pathname[MAX_PATHNAME], lpFileName[MAX_PATHNAME];

	// maio - rimosso perchè per questo progetto mi serve la possibiltà di 
	// disabilitare la hekkus!
#if 0
    hssUtility::fullPathName(pathname, name);
#endif


	// extract exe path
	GetModuleFileName(NULL, lpFileName, 255);

	// get the last backslash
	for (int i=_tcslen(lpFileName)-1; i>=0; i--) {
		if ( lpFileName[i] == _T('\\') ) {
			_stprintf(pathname, _T("%.*s"), i+1, lpFileName); 
			break;
		}
	}

	// append the filename
	_tcscat(pathname, name);

    f = _tfopen(pathname, _T("rb"));
    if (f == NULL)
        return false;

    LZAHeader lzah;
    fread(&lzah, sizeof(LZAHeader), 1, f);

    // se non è un .lza esco
    if (lzah.magic != LZA_MAGIC) {
        fclose(f);
        return false;
    }

    // recupero dati...
    m_numitems = lzah.numitems;
    m_totallength = lzah.totallength;

    m_open = true;

    return true;
}

void LZArchive::close() {

    if (m_open) {
        fclose(f);
        m_open = false;
    }
}


bool LZArchive::read(const TCHAR *name, LZItem *lzi) {

    // se l'archivio non è aperto o se lzi è già allocato esco...
    if ((m_open == false) || (m_numitems == 0))
        return false;
        
    if ((lzi->m_cprbuf) || (lzi->m_dcprbuf))
        return false;

    // cerco l'item...
    LZIHeader lzih;
    u32 p = sizeof(LZAHeader);
    while (p < m_totallength) {

        fseek(f, p, SEEK_SET);
        
        fread(&lzih, sizeof(LZIHeader), 1, f);

        // se è quello che cerco...
        char cname[128];
#ifdef _WIN32_WCE
        wcstombs(cname, name, 128); 
#else
        strcpy(cname, name);
#endif
		// Converto il nome in minuscolo
		for (unsigned int cc = 0; cc < strlen(cname); cc++)
			cname[cc] = tolower( cname[cc] );

        if (strcmp(cname, (char *)lzih.name) == 0) {

            u8 *buf;
            u32 length;
            // se il dato è compresso
            if (lzih.compressed)
                length = lzih.cprlength;
            else
                length = lzih.dcprlength;

            // alloco e leggo
            buf = new u8[length];
            if (buf == 0)
                return false;
            fread(buf, length, 1, f);

            // setto lzi in modo che deallochi buf
            if (lzih.compressed)
                lzi->cCreate(buf, length, lzih.dcprlength, true);
            else
                lzi->dCreate(buf, length, lzih.cprlength, true);

            return true;
        }
               
        // p al prossimo
        p += lzih.totallength;
    }

    return false;
}
