#pragma once

// Storm.h
//  Copyleft by Yuki Kamino

#include <tchar.h>
#include <stdio.h>
#include <CommDlg.h>
#include <time.h>
#include <math.h>
#include "resource.h"

#ifdef STRICT
#define CBTYPE WNDPROC
#else
#define CBTYPE FARPROC
#endif

typedef char *PCHAR;

enum
{
  TK_EOF, TK_ERROR, TK_NONE, TK_ID, TK_STR, TK_INT, TK_DBL, TK_UINT,
  TK_COMMA, TK_BEGINNAME, TK_ENDNAME, TK_IN, TK_OUT, TK_BEGIN, TK_END,
  TK_PLUS, TK_MINUS, TK_MULTI, TK_DIV, TK_COMM, TK_NEG, TK_NDIV, TK_MOD,
  TK_COMMON, TK_SCENE, TK_POW, TK_EQ, TK_NE, TK_LE, TK_LT, TK_GE, TK_GT,
  TK_AND, TK_OR, TK_AT, TK_COLON, TK_TEXT, TK_SETCHARSIZE, TK_COLOR,
  TK_FONT, TK_BOLD, TK_ITALIC, TK_UNDER, TK_TOP, TK_CENTER, TK_BOTTOM,
  TK_NUM, TK_VAL, TK_CELL, TK_CONTENTS, TK_WID, TK_FONTSIZE, TK_LET, TK_VAR,
  TK_VALLET, TK_NUMLET, TK_IF, TK_ELSE, TK_WORD, TK_WORDLET, TK_LIST, TK_IDNUM,
  TK_DATA, TK_LINK, TK_MEMO, TK_LISTDATA, TK_WORDMUL, TK_NAME, TK_DATE,
  TK_TIME, TK_SEC, TK_DOT, TK_STRITEM, TK_STRMULITEM, TK_TABLE, TK_CROSS, TK_CARD,
  TK_ITEM, TK_SET, TK_PATH, TK_SETMEASUREUNIT, TK_MU_CHAR, TK_MU_WCHAR, TK_MU_MM,
  TK_MU_INCH, TK_DATAFORMAT, TK_XITEM, TK_YITEM, TK_VITEM, TK_SETNUM, TK_SETRANK,
  TK_SELECT, TK_SORTUP, TK_SORTDOWN, TK_WORK, TK_DWELL, TK_PLAY, TK_RECT, TK_ELLIPSE,
  TK_HYPER, TK_TEMP, TK_CREATURE, TK_TIMER, TK_ONCLICK, TK_RED, TK_BLUE, TK_SIZE,
  TK_ONOFF, TK_COLORVAL, TK_CIRCLE, TK_ONEOF, TK_FOR, TK_STEP, TK_SELECTOR,
};

enum
{
  ET_NONE, ET_TEXT, ET_SETCHARSIZE, ET_CELL, ET_ASSIGN, ET_IF, ET_RECT, ET_ELLIPSE,
  ET_HYPER, ET_CREATURE, ET_FOR,
};

enum
{
  ST_NONE, ST_FIRST, ST_FOLLOW, ST_FONTIN, ST_FONTOUT, ST_COLORIN, ST_COLOROUT,
  ST_TOP, ST_CENTER, ST_BOTTOM, ST_FREE, ST_TABLE, ST_CROSS, ST_CARD,
  ST_INT, ST_DBL, ST_STR, ST_VAR1, ST_VAR2, ST_PATH,
  ST_IF, ST_ELSE, ST_TIME, ST_PATH1, ST_PATH2,
};

enum
{
  TI_NUM, TI_RANK, TI_PATH, TI_EXPR, TI_STR,
};

enum
{
  MU_CHAR, MU_WCHAR, MU_MM, MU_INCH,
};

enum
{
  VT_INT, VT_DBL, VT_STR,
};

enum
{
  ITEM_STR, ITEM_VAR, ITEM_EXPR,
};

// result of expression eval
enum
{
  EX_ERR, EX_INT, EX_DBL, EX_THRU, EX_DATE, EX_STR,
};

enum
{
  FT_ID, FT_STR, FT_STRMUL, FT_DBL, FT_INT, FT_LINK, FT_DATE, FT_TIME, FT_SEC,
};

enum
{
  OP_SELECT, OP_SORTUP, OP_SORTDOWN,
};

enum
{
  TF_TOP, TF_NEXT, TF_UP, TF_SUB, TF_SUP,
};

enum
{
  TM_PLAIN, TM_DOWN, TM_UP, TM_SUB, TM_SUP,
};

typedef struct tagParts
{
  int x1, y1, x2, y2;
  COLORREF col;
  int wid;
  struct tagParts *next;
} Parts;

typedef struct tagMic
{
  Parts *pParts;
  int x, y;
  struct tagMic *next;
} Mic;

typedef struct tagDataItem
{
  TCHAR *name;
  int type;
  struct tagDataSet *link;
  double wid;
  BOOL bTemp;
} DataItem;

typedef struct tagPath
{
  struct tagDataSet *pD;
  int len;
  int *ip;
  struct tagPath *next;
} Path;

typedef struct tagDataSet
{
  TCHAR *name;
  int type;
  int num;
  DataItem *item;
  int posID;
  int posName;
  int total;
  int *offset;
  int RecMax;
  int RecNum;
  PCHAR *RecData;
  PCHAR RecTemp;
  BOOL *bUsed;
  int LastID;
  int nStep;
  BOOL bTemp, bReadOnly;
  int nFile;
  int *pFile;
  struct tagEva **pEva;
  int numCode, maxCode;
  struct tagPath *pPathTop;
  struct tagDataSet *next;
} DataSet;

typedef struct tagTimer
{
  TCHAR *name;
  int goal;
} Timer;

typedef struct tagCreature
{
  TCHAR *name;
  BOOL bCol;
  COLORREF col;
  Timer *pTimer;
  int x1, x2, y1, y2;
  BOOL bOnClick;
  double cx1, cy1, cx2, cy2;
  struct tagEva **pEva;
  int numCode, maxCode;
  struct tagCreature *next;
} Creature;

typedef struct tagOnClick
{
  int x1, y1, x2, y2;
  int start, span, goal, time;
  Creature *pCreature;
  struct tagOnClick *next;
} OnClick;

typedef struct tagForce
{
  int pos;
  int nVal;
  double dVal;
  TCHAR *str;
  int nList, *pList;
  struct tagForce *next;
} Force;

typedef struct tagExpr
{
  int len;
  int *ip;
} Expr;

typedef struct tagVariable
{
  TCHAR *name;
  int type;
  int nVal;
  double dVal;
  TCHAR *str;
  struct tagVariable *next;
} Variable;

typedef struct tagAssign
{
  Variable *pVar;
  Expr expr;
  TCHAR *str;
  BOOL bOnce, bAlready;
} Assign;

typedef struct tagFontData
{
  TCHAR *name;
  int deciPt;
  BOOL bBold, bItalic, bUnder;
} FontData;

typedef struct tagCellItem
{
  int type;
  TCHAR *text;
  Variable *pVar;
  Expr expr;
  int dig;
  int wid;
  BOOL bWid;
  int rWid;
} CellItem;

typedef struct tagTableItem
{
  int type;
  int sub;
  double wid;
  Path *pPath;
  Expr expr;
  TCHAR *str;
} TableItem;

typedef struct tagCrossItem
{
  Path *pX;
  Path *pY;
  Path *pV;
  BOOL bOnOff;
} CrossItem;

typedef struct tagOpe
{
  int type;
  Path *pPath;
  Expr expr;
  struct tagOpe *next;
} Ope;

typedef struct tagCell
{
  int type;
  DataSet *pD;
  int nShow;
  int *pShow;
  int nW, nH;
  int nWid;
  double *pWid;
  int nItem;
  double w1, w2, w3;
  CellItem **pCellItem;
  TableItem *pTableItem;
  CrossItem *pCrossItem;
  Ope *topOpe;
} Cell;

typedef struct tagRuby
{
  TCHAR *parent;
  int len;
  TCHAR *ruby;
  struct tagRuby *next;
} Ruby;

typedef struct tagEva
{
  int type;
  int sub;
  double x, y;
  double dx, dy;
  double size;
  TCHAR *text;
  Ruby *topRuby;
  Variable *pVar;
  int dig;
  double wid;
  FontData *pFontData;
  Cell *pCell;
  Assign *pAssign;
  double x1, y1, x2, y2;
  COLORREF col;
  BOOL bCol;
  int skip;
  Expr expr;
  Path *pPath;
  BOOL bOnClick;
  OnClick *pOnClick;
  Creature *pCreature;
  struct tagFor *pFor;
  struct tagHyper *pHyper;
} Eva;

typedef Eva* PEVA;

typedef struct tagFor
{
  DataSet *pD;
  int rec;
  PEVA *pEva;
  int nShow, *pShow;
  int numCode, maxCode;
  Ope *topOpe;
} For;

typedef struct tagHyper
{
  PEVA *pEva;
  int numCode, maxCode;
  int x1, y1, x2, y2;
} Hyper;

typedef struct tagAra
{
  int type;
  int rec;
  double x, y;
  BOOL bCol;
  COLORREF col;
  Eva *pMom;
  OnClick *pOnClick;
} Ara;

typedef Ara* PARA;
typedef PARA* PPARA;

typedef struct tagText
{
  TCHAR *text;
  int x, y;
  COLORREF col;
  LOGFONT lf;
  int size;
  int nForm;
  struct tagText *next;
} Text;

typedef struct tagSet
{
  TCHAR *name;
  PEVA *pEva;
  int numCode, maxCode;
  Variable *varTop;
  int x1, y1, x2, y2;
  Text *textTop;
  BOOL bBack;
  COLORREF colBack;
  struct tagSet *next;
} Set;

typedef struct tagRecNo
{
  int rec;
  int no;
} RecNo;

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void AddBD(TCHAR *str);
void AddEva(Eva *p);
void AddVariable(Set *pSet, Variable *p);
int CellLen(Cell *pCell);
int CellWid(Cell *pCell);
double CellWidOne(Cell *pCell, int x);
int CheckDirtyFlag(HWND hWnd);
BOOL CheckHyper(int x, int y);
BOOL CheckKeywordOrder();
BOOL CheckNum();
BOOL CheckText();
BOOL CheckToken(int token, BOOL bNoDot = FALSE);
void ClearBD();
void ClearColor();
void ClearFont();
void ClearSet(Set *p);
void ClearStrIn();
void ColorBox(HWND hDlg);
void CompleteField();
DataItem *DblField(TCHAR *name);
void DeleteRecord(DataSet *pD, int rec);
void DoOpenA();
INT_PTR CALLBACK EditArasi(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
int Eval(Expr *p);
DataSet *FindDataSet(TCHAR *name);
int FindItem(DataSet *pD, TCHAR *name);
Path *FindPath(DataSet *pD, TCHAR *name);
Variable *FindVar(TCHAR *name);
Variable *FindVariable(Set *pSet, TCHAR *name);
void FontBox(HWND hDlg);
HFONT GetBodyFont(BOOL bPrn, double size, BOOL bUnder);
BOOL GetContents(BOOL bSingle);
TCHAR *GetDataAsStr(DataSet *pD, int rec, int pos, BOOL bSave);
double GetDataDbl(DataSet *pD, int rec, int pos);
int GetDataInt(DataSet *pD, int rec, int pos);
BOOL GetDataSet(int type);
TCHAR *GetDataStr(DataSet *pD, int rec, int pos);
HFONT GetDefFont(BOOL bPrn, BOOL bFix = FALSE);
BOOL GetExpr(Expr *p);
HFONT GetFont(TCHAR *name, double size, BOOL bBold, BOOL bItalic, BOOL bUnder, BOOL bPrn, BOOL bFix = FALSE);
HFONT GetHyperFont();
BOOL GetOpenFile(HWND hWnd, BOOL bApp);
TCHAR *GetPathAsStr(Path *pPath, int rec);
double GetPathDbl(Path *pPath, int rec);
int GetPathInt(Path *pPath, int rec);
TCHAR *GetPathName(Path *pPath);
TCHAR *GetPathStr(Path *pPath, int rec);
int GetPathType(Path *pPath);
HPEN GetPen(int wid, COLORREF col);
BOOL GetSaveFile(HWND hWnd, BOOL bApp);
int GetTermRec(Path *p, int rec);
int GetToken(BOOL bNoDot = FALSE);
int FindIDData(DataSet *pD, int id);
void IDSort(DataSet *pD);
DataItem *IntField(TCHAR *name);
int NextID(DataSet *pD, BOOL bLas);
void OnClose(HWND hWnd);
void OnOpenA(HWND hWnd);
void OnOpenD(HWND hWnd);
void OnPaint(HWND hWnd, HDC hDC, BOOL bPrn);
void OnPrint(HWND hWnd);
void OnSaveA(HWND hWnd, BOOL bOver);
void OnSaveAsD(HWND hWnd);
void OnSaveD(HWND hWnd);
void OnTimerClick(HWND hWnd);
BOOL ParseAaf(TCHAR *in);
int PathType(Path *p);
int PathWid(Path *p);
int PixX(double x, BOOL bPrn);
int PixY(double y, BOOL bPrn, BOOL bAdd);
HFONT PopFont(HDC hDC);
void PushFont(HFONT hFont, HDC hDC);
void Renew();
void SetDataDbl(DataSet *pD, int rec, int pos, double dVal);
void SetDataInt(DataSet *pD, int rec, int pos, int nVal);
void SetDataStr(DataSet *pD, int rec, int pos, TCHAR *str);
TCHAR *GetPathExt(Path *pPath, int rec);
void SetPathDbl(Path *pPath, int rec, double x);
void SetPathInt(Path *pPath, int rec, int n);
void ShowBD();
int StdInputDialog(HWND hWnd, int rec);
int StrToDate(TCHAR *str);
void SwapRecTo(DataSet *pD, int rec);
int ThisDay(int mode = 0);
TCHAR *TokenStr(int token);
void UngetToken(int token);
TCHAR *ValToStr(double x, int dig, BOOL bAdd);
void ZapRecord(DataSet *pD);


extern HWND hMainWnd;
extern TCHAR *srcArasi, *srcOld;
extern TCHAR *topBuf;
extern int lineNo;
extern TCHAR strErrMsg[];
extern TCHAR nameIn[];
extern TCHAR *textIn;
extern TCHAR *strIn;
extern int nVal;
extern double dVal;
extern int lenInt;
extern unsigned int uVal;
extern int backedToken;
extern Set *topSet;
extern Set *curSet;
extern int crtXRes, crtYRes;
extern int prnXRes, prnYRes;
extern int curMeasUnit;
extern double measFactor;
extern double curPoint;
extern Ara *pAra;
extern int numAra, maxAra;
extern HINSTANCE hInst;
extern LOGFONT lfSelect;
extern int sizeSelect;
extern double defFontSize;
extern double defCellWid;
extern int topOffset;
extern int codePos;
extern DataSet *pDataSetTop;
extern BOOL bDirtyFlagD; /////////////////////
extern BOOL bDirtyFlagA; /////////////////////////
extern int insRec;
extern int evalRec;
extern DataSet *pDStd;
extern TCHAR FileName[], FileTitle[];
extern TCHAR AppFile[];
extern DataSet *curData;
extern BOOL bInExpr;
extern Parts *partsTop;
extern Parts *partsArr[];
extern int partsNum;
extern int partsAt;
extern HPEN hPenRed;
extern TCHAR *strHyper;
extern COLORREF colParts;
extern int widParts;
extern Mic *micTop;
extern RECT rcp;
extern BOOL bCodeMode;
extern Creature *topCreature, *curCreature;
extern OnClick *topOnClick, *curOnClick;
extern int startTime;
extern COLORREF colValue;
extern For *curFor;
extern Hyper *curHyper;
extern PARA *pHyper;
extern int numHyper, maxHyper;
extern Ara *curHyperAra;