#ifndef MAIN_H
#define MAIN_H
#include <apps.h>			
#include <typedefs.h>
#include <memory.h>
#include <events.h>
#include <uis.h>			
#include <resources.h>
#include <res_def.h>
#include <fs.h>
#include <synlib.h>
#include <dl.h>
#include <loader.h>
#include "..\dbg\dbg.h"

#define bool int
#define false 0
#define true 1

WCHAR filename[256];
WCHAR *cfgbuf=NULL;
WCHAR *temname=NULL;
WCHAR *map=NULL;
UINT32 mapid=0x10c3e800;
//[]=L"/a/mobile/skin/rar.tem";  

//int abs(int a){ return (a<0)?-a:a;}



//int in, outhandle;
BOOL tembuff=FALSE;
INT32 err;
FILE_HANDLE_T fr=FILE_INVALID,fw=FILE_INVALID;
size_t rd,wr;


int HeadType, Flags, HeadSize, PackSize, UnpSize, Version, Method, NameSize, NextPos;
int Attrib, AllSize;
//const int MAX_SIZE = 0x8000;
#define MAX_SIZE  0x1000

#define MAXWINSIZE  0x10000

#define MAXWINMASK  MAXWINSIZE-1


const  int SIZEOF_SHORTBLOCKHEAD =  7;
const  int LHD_SOLID  = 0x10;
const  int ATTR_SUB  = 0x10;

const int LOW_DIST_REP_COUNT = 16;
const int BLOCK_LZ=0, BLOCK_PPM=1;

unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};

int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
char DBits[]=  {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,  6,  6,  7,  7,  8,  8,   9,   9,  10,  10,  11,  11,  12,   12,   13,   13,    14,    14,   15,   15,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16};

int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};


#define NC 299
#define DC  60
#define LDC 17
#define RC  28
#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
#define BC  20

#define NC20 298
#define DC20 48
#define RC20 28
#define BC20 19
#define MC20 257

int LLSize[]={NC,DC,RC,BC,LDC, NC20,DC20,RC20,BC20,MC20,MC20,MC20,MC20};
int DecodeN[NC+DC+RC+BC+LDC+ NC20+DC20+RC20+BC20+MC20*4];

struct Decode{
  int MaxNum;
  int DecodeLen[16];
  int DecodePos[16];
  int DecodePtr;
  int DecodeCnt;
} LL[13];

void InitLL(){
  int i,j;
  for(i=j=0;i<13;i++){
    LL[i].DecodePtr=j;
    LL[i].DecodeCnt=LLSize[i];
    j+=LLSize[i];
  }
}

struct AudioVariables
{
  int K1,K2,K3,K4,K5;
  int D1,D2,D3,D4;
  int LastDelta;
  int Dif[11];
  int ByteCount;
  int LastChar;
};
/***************************** Unpack v 2.0 *********************************/


    int UnpRead(char *Window,int UnpPtr);
    void UnpWrite(char *Window,int UnpPtr);

    char UnpOldTable[HUFF_TABLE_SIZE];
    char *Window=0;
    char *InBuf=0;
	char *tembuf=0;
    int InAddr, InBit;

    void InitBitInput(){
      InAddr=InBit=0;
    }
    void addbits(int Bits){
      Bits+=InBit;
      InAddr+=Bits>>3;
      InBit=Bits&7;
    }
    int getbits(){
      int BitField=(InBuf[InAddr]&0xff) << 16;
      BitField|=(InBuf[InAddr+1]&0xff) << 8;
      BitField|=(InBuf[InAddr+2]&0xff);
      BitField >>= (8-InBit);
      return(BitField & 0xffff);
    }
    void Unpack29(bool Solid);
    bool UnpReadBuf(void);
    void UnpWriteBuf(void);
    void UnpWriteArea(int StartPtr,int EndPtr);
    void UnpWriteData(char *Data,int Size);
    bool ReadTables(void);
    void MakeDecodeTables(char *LenTab,int pos);
    int DecodeNumber(int pos);
    void UnpInitData(int Solid);

    bool ReadEndOfBlock(void);
    void CopyString(int Length,int Distance);
     void InsertOldDist(int Distance);
     void InsertLastMatch(int Length,int Distance);
    int PPMEscChar;
    int LastFilter;
    bool TablesRead;
    int OldDist[4],OldDistPtr;
    int LastDist,LastLength;
    int UnpPtr,WrPtr,off;
    int ReadTop;
    int ReadBorder;

    int UnpBlockType;
    int DestUnpSize;

    bool Suspended;
    bool UnpAllBuf;
    bool UnpSomeRead;
    int WrittenFileSize;
    bool FileExtracted;
    bool PPMError;

    int PrevLowDist,LowDistRepCount;


/***************************** Unpack v 1.5 *********************************/
#ifdef OTHER
    void Unpack15(bool Solid);
    void ShortLZ(void);
    void LongLZ(void);
    void HuffDecode(void);
    void GetFlagsBuf(void);
    void OldUnpInitData(int Solid);
    void InitHuff(void);
    void CorrHuff(int *CharSet,int *NumToPlace);
    void OldCopyString(int Distance,int Length);
    int DecodeNum(int Num,int StartPos,
      int *DecTab,int *PosTab);
    void OldUnpWriteBuf(void);

    int ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
    int Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
    int NToPl[256],NToPlB[256],NToPlC[256];
    int FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
    int Buf60,NumHuf,StMode,LCount,FlagsCnt;
    int Nhfb,Nlzb,MaxDist3;

    void Unpack20(bool Solid);
    char UnpOldTable20[MC20*4];
    int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta;
    void CopyString20(int Length,int Distance);
    bool ReadTables20(void);
    void UnpInitData20(int Solid);
    void ReadLastTables(void);
    char DecodeAudio(int Delta);

    struct AudioVariables AudV[4];

    void DoUnpack(int Method,bool Solid);
    bool IsFileExtracted(void) {return(FileExtracted);}
    void SetDestSize(int DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
    void SetSuspended(bool Suspend) {Suspended=Suspend;}
#endif

typedef struct {
    UINT32        R0;
    UINT32        R1;
} _u64;


UINT32 Register( char * file_uri, char * param, UINT32 reserve );
UINT32 util_asc2ul( const char * s, UINT32 count );
UINT32 param2uri(char *param,WCHAR *uri);
const char	app_name[APP_NAME_LEN] = "unrar";
void UnpackLose(void);
UINT16 GBToUCS2( WCHAR* u_buf,char* g_buf);
#endif