#ifndef MODEX_HH
 #define MODEX_HH

#include "video.hh"     //My abstract base class
#include "videodef.hh"  //Video mode defines such as 'VGA_320x240x256'
#include "typedef.hh"	//Type defines such as 'unsigned char' means 'UBYTE'
#include "bitmap.hh"

class ModeX : public Video
{
public:
  ModeX(void);
  ~ModeX(void);
  UBYTE SetResolution(BYTE theMode, UWORD viewport); //Initialize custom unchained VGA mode
  UBYTE GetNrOfPages(void);
  void SetDrawPage(unsigned int thePage);
  void SetVisiblePage(unsigned int thePage);
  void ClearScreen(UBYTE theColor);
  void ClearVideoMemory(UBYTE theColor);
  void ScrollX(WORD direction);
  void ScrollY(WORD direction);
  void SetScrollingSpeed(UWORD ySpeed);
  void ClearScrollingY(void);
  void ClearScrollingX(void);
  void PutPixel(WORD x, WORD y, UBYTE color);
  UBYTE GetPixel(WORD x, WORD y);
  void V_Line(WORD x, WORD top_y, WORD len, UBYTE color);
  void H_Line(WORD left_x, WORD y, WORD len, UBYTE color);
  void Box(WORD x1, WORD y1, WORD x2, WORD y2, UBYTE color);
  void FilledBox(WORD x1, WORD y1, WORD x2, WORD y2, UBYTE color);
  void Circle(WORD x, WORD y, WORD r, UBYTE color);
  void FilledCircle(WORD x, WORD y, WORD r, UBYTE color);
  void Line(WORD x1, WORD y1, WORD x2, WORD y2, UBYTE color);
  void DrawAnySizeBitmap(WORD x, WORD y, Bitmap *myBitmap);
  void DrawAlignedBitmap(WORD x, WORD y, Bitmap *myBitmap);
  void GetAnySizeRAMBitmap(WORD x, WORD y, WORD theWidth, WORD theHeight, Bitmap *mySrc, Bitmap *myDst);
  void GetAlignedRAMBitmap(WORD x, WORD y, WORD theWidth, WORD theHeight, Bitmap *mySrc, Bitmap *myDst);
  WORD ScaleBitmap(Bitmap* srcBmp, Bitmap* dstBmp, int newXSize, int newYSize);
  WORD ScaleBitmapX(Bitmap* srcBmp, Bitmap* dstBmp, int newXSize);
  WORD ScaleBitmapY(Bitmap* srcBmp, Bitmap* dstBmp, int newYSize);
  void ConvLin2PlanBitmap(Bitmap *myBitmap);
  void ConvPlan2LinBitmap(Bitmap *myBitmap);  
  void DrawCompiledBitmap(WORD x,WORD y,Bitmap *myBitmap);
  UBYTE CompileBitmap(Bitmap *myBitmap);
  void DrawWideBitmap(WORD y, Bitmap *myBitmap);
  void GetWideScreenBitmap(WORD y, WORD height, Bitmap *myBitmap);
  void GetAlignedScreenBitmap(WORD x, WORD y, WORD width, WORD height, Bitmap *myBitmap);
  void GetAnySizeScreenBitmap(WORD x, WORD y, Bitmap *myBitmap);
private:
  void CalcRows(void);
  UBYTE AllocRLEBitmap(Bitmap *myBitmap);
  void internal_xmajor(UBYTE *vga_ptr, short int len, short int yskip,
		       unsigned long ErrorAcc, unsigned long ErrorAdj, UBYTE color);
  void internal_middle(UBYTE *vga_ptr, short int len, short int yskip,
		       unsigned long ErrorAcc, unsigned long ErrorAdj, UBYTE color);
  void internal_ymajor(UBYTE *vga_ptr, short int len, short int yskip,
		       unsigned long ErrorAcc, unsigned long ErrorAdj, UBYTE color);
  
  UBYTE *RowsX[664];
  UWORD currentPageOffset;
  UWORD page_offset[5];
  UWORD PageOffset[5];
  UWORD page_mask_high[5];
  UWORD page_mask_low[5];
  UWORD viewPortByteSize;
  UWORD scrollYMaskHigh[64 * 5];
  UWORD scrollYMaskLow[64 * 5];
  WORD scrollYvalue;
  UWORD scrollYSpeed;
  WORD scrollXvalue;
  UWORD scrollXSpeed;
  unsigned short plane_mask[4];
  unsigned short read_mask[4];
  unsigned char line_head[4];
  unsigned char line_tail[4];
};

#endif
