#ifndef _WSCSHEET_H
#define _WSCSHEET_H

#include <WScom.h>
#include <WSCform.h>
#include <WSCsheetListData.h>
#include <WSCvdb.h>
#include <WSCdb.h>
#include <WSCsheetdef.h>
#include <WSDkeyboard.h>

#define WSsheet_VER                    1000

#define WSCSHEET_DEFAULT               -1

#define WSCSHEET_NONE                  0
#define WSCSHEET_HORZ                  1
#define WSCSHEET_VERT                  2
#define WSCSHEET_BOTH                  3

#define WSCSHEET_DEF_ROW_HEIGHT        20
#define WSCSHEET_DEF_COL_WIDTH         80

#define WSCSHEET_DEFCOLOR              0
#define WSCSHEET_DEFFONT               -1

#define WSCSHEET_DEF_ROWS              51
#define WSCSHEET_DEF_COLS              11
#define WSCSHEET_DEF_FIXEDROWS         1
#define WSCSHEET_DEF_FIXEDCOLS         1

#define WSCSHEET_CELL_NOLOCK           False
#define WSCSHEET_CELL_LOCK             True

#define WSCSHEET_DB_SORT_ASC           0
#define WSCSHEET_DB_SORT_DESC          1


class WSCvscrBar;
class WSCvifield;

class WSCsheetCell
{
public:
    WSCsheetCell()
    {
        lock = WSCSHEET_CELL_NOLOCK;
        align = WS_LEFT;
        text.clear();
        crBkClr = WSCSHEET_DEFCOLOR;
        crFgClr = WSCSHEET_DEFCOLOR;
        fontno = WSCSHEET_DEFFONT;
        crLine = WSCSHEET_DEFAULT;
    }

public:
    WSCbool       lock;                // Cell Edit Lock (or WSCSHEET_CELL_NOLOCK)
    char          align;               // Cell text align (or WS_LEFT)
    WSCstring     text;                // Cell text (or binary data if you wish...)
    short         crBkClr;             // Background colour (or WSCSHEET_DEFCOLOR)
    short         crFgClr;             // Forground colour (or WSCSHEET_DEFCOLOR)
    short         fontno;              // Cell font (or WSCSHEET_DEFFONT)
    short         crLine;              // Cell Line Type (or WSCSHEET_DEFAULT)
}; 

class WSCsheetRow
{
public:
    WSCsheetRow(long cols, long height = WSCSHEET_DEFAULT)
    {
        _height = height;
        setColSize(cols);
    }
    void clear()
    {
        long num = _colData.getNum();
        for(long col = 0; col < num; col++) {
            WSCsheetCell* coldata = (WSCsheetCell*)_colData.getData(col);
            delete coldata;
        }
        _colData.clear();
    }
    void setRowHeight(long height) { _height = height; }
    long getRowHeight() { return _height; }
    long setColSize(long cols)
    {
        _colData.setSize(cols);
        return WS_NO_ERR;
    }
    WSCsheetCell* newCell(long col)
    {
        WSCsheetCell* cell = new WSCsheetCell();
        _colData.setData(col, cell);
        return cell;
    }
    WSCsheetCell* getCell(long col)
    {
        WSCsheetCell* cell = (WSCsheetCell*)_colData.getData(col);
        return cell;
    }
    long insertCol(long col, long cols)
    {
        long num = _colData.getNum();
        for(long count = 0; count < cols; count++) {
            WSCsheetCell* coldata = new WSCsheetCell();
            _colData.add(coldata, col);
        }
        setColSize(num);
        return WS_NO_ERR;
    }
    long deleteCol(long col, long cols)
    {
        long num = _colData.getNum();
        long max = num - col;
        for(long count = 0; (count < cols) && (count < max); count++) {
            WSCsheetCell* coldata = (WSCsheetCell*)_colData.getData(col);
            delete coldata;
            _colData.delPos(col);
        }
        setColSize(num);
        return WS_NO_ERR;
    }
public:
    long             _height;
    WSCsheetListData _colData;
};


class WSCsheet : public WSCform
{
public:
    WSCsheet(WSCbase* parent, char* name);
    virtual ~WSCsheet();

    virtual long initialize();
    virtual long clear(long col = WSCSHEET_DEF_COLS, long row = WSCSHEET_DEF_ROWS);
    virtual long draw();
    virtual long redraw();
    virtual long cdraw();
    virtual void update();

    virtual void onResize(WSCrect* rect);
    virtual void onMouseMove(WSCpoint* pt);
    virtual void onMousePress(WSCpoint* pt);
    virtual void onMouseRelease(WSCpoint* pt);
    virtual void onVisibleChange(WSCbool vis);

public:
    long      getRowCount() const { return _rows; }
    long      setRowCount(long rows = WSCSHEET_DEF_ROWS);
    long      getColumnCount() const { return _cols; }
    long      setColumnCount(long cols = WSCSHEET_DEF_COLS);

    long      getRowHeight(long row);
    long      setRowHeight(long row, long height);
    long      getColumnWidth(long col);
    long      setColumnWidth(long col, long width);
   
    long      getFixedRowCount() const { return _fixedRows; }
    long      setFixedRowCount(long fixedRows = WSCSHEET_DEF_FIXEDROWS);
    long      getFixedColumnCount() const { return _fixedCols; }
    long      setFixedColumnCount(long fixedCols = WSCSHEET_DEF_FIXEDCOLS);

    long      getFixedRowHeight(long row);
    long      setFixedRowHeight(long row, long height);
    long      getFixedColumnWidth(long col);
    long      setFixedColumnWidth(long col, long width);

    long      setSheetBkColor(char* cname);
    long      setSheetBkColor(short color);
    short     getSheetBkColor() const { return _sheetBackColor; }

    long      setCellDefBkColor(char* cname);
    long      setCellDefBkColor(short color);
    short     getCellDefBkColor() const { return _cellBackColor; }

    long      setCellBkColor(char* cname);
    long      setCellBkColor(long col, long row, char* cname);
    long      setCellBkColor(short color);
    long      setCellBkColor(long col, long row, short color);
    short     getCellBkColor(long col, long row);

    long      setCellDefTextColor(char* cname);
    long      setCellDefTextColor(short color);
    short     getCellDefTextColor() const { return _cellTextColor; }

    long      setCellTextColor(char* cname);
    long      setCellTextColor(long col, long row, char* cname);
    long      setCellTextColor(short color);
    long      setCellTextColor(long col, long row, short color);
    short     getCellTextColor(long col, long row);

    long      setFixedBkColor(char* cname);
    long      setFixedBkColor(short color);
    short     getFixedBkColor() const { return _fixedBackColor; }

    long      setFixedTextColor(char* cname);
    long      setFixedTextColor(short color);
    short     getFixedTextColor() const { return _fixedTextColor; }

    long      setGridColor(char* cname);
    long      setGridColor(short color);
    short     getGridColor() { return _gridColor; }

    long      setGridLines(short glidLines = WSCSHEET_BOTH);
    short     getGridLines() const { return _gridLines; }

    long      setCellGridLines(short glidLines = WSCSHEET_BOTH);
    long      setCellGridLines(long col, long row, short glidLines = WSCSHEET_BOTH);
    short     getCellGridLines(long col, long row);

    long      setText(short text);
    long      setText(WSCushort text);
    long      setText(long text);
    long      setText(WSCulong text);
    long      setText(float text);
    long      setText(double text);
    long      setText(const char* text);
    long      setText(const WSCvariant& text);
    long      setText(const WSCstring& text);
    long      setText(long col, long row, short text);
    long      setText(long col, long row, WSCushort text);
    long      setText(long col, long row, long text);
    long      setText(long col, long row, WSCulong text);
    long      setText(long col, long row, float text);
    long      setText(long col, long row, double text);
    long      setText(long col, long row, const char* text);
    long      setText(long col, long row, const WSCvariant& text);
    long      setText(long col, long row, const WSCstring& text);
    WSCstring getText(long col, long row);

    long      setFixedText(long col, long row, short text);
    long      setFixedText(long col, long row, WSCushort text);
    long      setFixedText(long col, long row, long text);
    long      setFixedText(long col, long row, WSCulong text);
    long      setFixedText(long col, long row, float text);
    long      setFixedText(long col, long row, double text);
    long      setFixedText(long col, long row, const char* text);
    long      setFixedText(long col, long row, const WSCvariant& text);
    long      setFixedText(long col, long row, const WSCstring& text);
    WSCstring getFixedText(long col, long row);

    long      getCellNo(WSCpoint* pt, long* col, long* row);

    long      setFocusCell(long col, long row);
    void      getFocusCell(long* col, long* row) { *col = _focusCol; *row = _focusRow; }
    long      getFocusCol() { return _focusCol; }
    long      getFocusRow() { return _focusRow; }
    
    void      setRow(long row);
    long      getRow() { return _startRow; }
    void      setStartRow(long row);
    long      getStartRow() { return (_startRow <= _endRow ? _startRow : _endRow); }
    void      setEndRow(long row);
    long      getEndRow() { return (_startRow > _endRow ? _startRow : _endRow); }

    void      setCol(long col);
    long      getCol() { return _startCol; }
    void      setStartCol(long col);
    long      getStartCol() { return (_startCol <= _endCol ? _startCol : _endCol); }
    void      setEndCol(long col);
    long      getEndCol() { return (_startCol > _endCol ? _startCol : _endCol); }

    void      setSelectCell(WSCbool val);
    WSCbool   getSelectCell() { return _selectCell; }

    void      setEditEnabled(WSCbool val) { _editEnabled = val; }
    WSCbool   getEditEnabled() { return _editEnabled; }

    long      getFocusCellRect(WSCrect* rect);
    long      getVisibleCellRect(long col, long row, WSCrect* rect);
    long      getCellRect(long col, long row, WSCrect* rect);

    long      setTopVisibleRow(long row);
    long      getTopVisibleRow() { return _topVisibleRow; };
    long      setTopVisibleCol(long col);
    long      getTopVisibleCol() { return _topVisibleCol; };

    long      setCellDefFont(short fontno);
    short     getCellDefFont() { return _font; }

    long      setCellFont(short fontno);
    long      setCellFont(long col, long row, short fontno);
    short     getCellFont() { return _font; }
    short     getCellFont(long col, long row);
    
    long      setFixedCellFont(short fontno);
    short     getFixedCellFont() { return _fixedFont; }

    void      setVertAutoNumber(WSCbool val) { _vautoNumber = val; }
    WSCbool   getVertAutoNumber() { return _vautoNumber; }
    void      setHorzAutoNumber(WSCbool val) { _hautoNumber = val; }
    WSCbool   getHorzAutoNumber() { return _hautoNumber; }

    long      setCellAlignemnt(char align);
    long      setCellAlignemnt(long col, long row, char align);
    char      getCellAlignemnt(long col, long row);

    long      setFixedCellAlignemnt(long col, long row, char align);
    char      getFixedCellAlignemnt(long col, long row);

    long      setCellLock(WSCbool lock);
    long      setCellLock(long col, long row, WSCbool lock);
    WSCbool   getCellLock(long col, long row);
    
    WSCushort getClientWidth() { return _clientWidth; }
    WSCushort getClientHeight() { return _clientHeight; }
    
    void      setNoRefresh(WSCbool val) { _no_refresh = val; }
    WSCbool   getNoRefresh() { return _no_refresh; }
    
    long      insertRow();
    long      insertRow(long row, long rows);
    long      insertCol();
    long      insertCol(long col, long cols);
    
    long      deleteRow();
    long      deleteRow(long row, long rows);
    long      deleteCol();
    long      deleteCol(long col, long cols);

    /// database 
    long      setDataSource(const char* name);
    long      setDataSource(WSCstring& name);
    WSCstring getDataSource() { _dbwork = _dataSource; return _dbwork; }

    long      setTableName(const char* table);
    long      setTableName(WSCstring& table);
    WSCstring getTableName() { _dbwork = _tableName; return _dbwork; }
    
    long      setDbItem(const char* item);
    long      setDbItem(WSCstring& item);
    WSCstring getDbItem() { _dbwork = _dbItem; return _dbwork; }

    long      setDbSortItem1(const char* item);
    long      setDbSortItem1(WSCstring& item);
    WSCstring getDbSortItem1() { _dbwork = _dbSortItem1; return _dbwork; }

    long      setDbSort1(WSCuchar sort);
    WSCuchar  getDbSort1() { return _dbSort1; }

    long      setDbSortItem2(const char* item);
    long      setDbSortItem2(WSCstring& item);
    WSCstring getDbSortItem2() { _dbwork = _dbSortItem2; return _dbwork; }

    long      setDbSort2(WSCuchar sort);
    WSCuchar  getDbSort2() { return _dbSort2; }

    long      setDbSortItem3(const char* item);
    long      setDbSortItem3(WSCstring& item);
    WSCstring getDbSortItem3() { _dbwork = _dbSortItem3; return _dbwork; }

    long      setDbSort3(WSCuchar sort);
    WSCuchar  getDbSort3() { return _dbSort3; }
    
    long      setDbFilter(const char* filter);
    long      setDbFilter(WSCstring& filter);
    WSCstring getDbFilter() { _dbwork = _dbFilter; return _dbwork; }

    long      setDbStmtString(const char* stmt);
    long      setDbStmtString(WSCstring& stmt);
    WSCstring getDbStmtString() { _dbwork = _dbStmtString; return _dbwork; }

    long      dbRefresh();
    long      dataClear(long col = 2, long row = 2);

protected:
    virtual   long _device_initialize();
    static    void onHscroolClick(WSCbase* obj);
    static    void onVscrollClick(WSCbase* obj);
    static    void onEditFocusChange(WSCbase* obj);
    static    void onSheetExpose(WSCbase* obj);
    static    void onSheetMouseMove(WSCbase* obj);
    static    void onSheetMousePress(WSCbase* obj);
    static    void onSheetMouseRelease(WSCbase* obj);
    virtual   void onScrMouseMove(WSCpoint* pt);
    virtual   void onScrMousePress(WSCpoint* pt);
    virtual   void onScrMouseRelease(WSCpoint* pt);
    static    void onEditActivate(WSCbase* obj);
    static    void onEditKeyPress(WSCbase* obj);
    static    void onEditKeyRelease(WSCbase* obj);
    static    void onEditKeyHook(WSCbase* obj);
    static    void onEditValueChange(WSCbase* obj);
    virtual   void onActivate();
    virtual   void onKeyPress(WSDkeyboard* keyboard);
    virtual   void onKeyRelease(WSDkeyboard* keyboard);
    virtual   void onKeyHook(WSDkeyboard* keyboard);
    virtual   void onValueChange();

    WSMFguiClassDef(WSCsheet, WSCform);
    WSMFversionDef(WSsheet);

    long      setCellText(const WSCstring& text);
    long      setCellText(long col, long row, const WSCstring& text);
    WSCstring getCellText(long col, long row);
    long      setFixedCellText(long col, long row, const WSCstring& text);
    WSCstring getFixedCellText(long col, long row);
    void      adjustScrollBar();
    char*     getUseScrBarClass();
    long      drawFixedCell(WSDdev* dev, long col, long row, WSCrect rect);
    long      drawCell(WSDdev* dev, long col, long row, WSCrect rect);
    long      rowSize(long rows);
    long      colSize(long cols);
    void      setRowCol(long col, long row);
    void      focusCellVisible(long coldCol, long oldRow, long newCol, long newRow);
    void      posMoveCell(WSCpoint* pt);
    long      getWidthValue(long col);
    void      setEndVisibleRow(long row) { _endVisibleRow = row; };
    long      getEndVisibleRow() { return _endVisibleRow; };
    void      setEndVisibleCol(long col) { _endVisibleCol = col; };
    long      getEndVisibleCol() { return _endVisibleCol; };
    
    WSCsheetCell* getCell(long col, long row, WSCbool alloc = False);
    WSCsheetRow*  getRowData(long row);
    long*         getWidthData(long col);

    long      dbConnect();
    long      setFixedCelldbItem(WSCdbRecord* rs);
    long      dbDataSet();
    WSCstring getDbErrorMsg();
    

protected:
    long        _rows;
    long        _cols;
    long        _fixedRows;
    long        _fixedCols;
    short       _gridLines;

    long        _colHeight;
    long        _colWidth;
    long        _fixedColHeight;
    
    long        _topVisibleRow;
    long        _topVisibleCol;
    long        _endVisibleRow;
    long        _endVisibleCol;
    long        _focusRow;
    long        _focusCol;
    long        _startRow;
    long        _startCol;
    long        _endRow;
    long        _endCol;

    WSCushort   _clientWidth;
    WSCushort   _clientHeight;
    WSCushort   _bar_thick;

    short       _font;
    short       _fixedFont;
    
    WSCbool     _mousepress;
    WSCbool     _mouseSelect;
    WSCbool     _selectCell;
    WSCbool     _editEnabled;
    WSCbool     _hautoNumber;
    WSCbool     _vautoNumber;
    WSCbool     _initVisible;
    
    WSCform*    _sheet;
    WSCvscrBar* _hscrBar;
    WSCvscrBar* _vscrBar;
    WSCvifield* _edit;

    short       _sheetBackColor;
    short       _cellBackColor;
    short       _cellTextColor;
    short       _fixedBackColor;
    short       _fixedTextColor;
    short       _gridColor;
    short       _selectBackColor;
    
    WSCsheetListData _rowData;
    WSCsheetListData _colWidthData;
    WSCsheetCell     _defCell;
    
    /// database
    WSCvdb*     _vdb;
    char*       _dataSource;
    char*       _tableName;
    char*       _dbItem;
    char*       _dbSortItem1;
    char*       _dbSortItem2;
    char*       _dbSortItem3;
    char*       _dbFilter;
    char*       _dbStmtString;
    WSCuchar    _dbSort1;
    WSCuchar    _dbSort2;
    WSCuchar    _dbSort3;
    WSCstring   _dbwork;
    WSCbool     _dbCellAutoResize;
    WSCbool     _dbCellTitle;
    WSCstring   _dbError;
    
protected:
    WSMFpropertyDef(WSNrows, long, _rows);
    WSMFpropertyDef(WSNcols, long, _cols);
    WSMFpropertyDef(WSNfixedRows, long, _fixedRows);
    WSMFpropertyDef(WSNfixedCols, long, _fixedCols);
    WSMFpropertyDef(WSNgridLines, short, _gridLines);
    WSMFpropertyDef(WSNcellDefWidth, long, _colWidth);
    WSMFpropertyDef(WSNcellDefHeight, long, _colHeight);
    WSMFpropertyDef(WSNfixedColHeight, long, _fixedColHeight);
    WSMFpropertyDef(WSNcellDefFont, short, _font);
    WSMFpropertyDef(WSNfixedCellFont, short, _fixedFont);
    WSMFpropertyDef(WSNeditEnabled, WSCbool, _editEnabled);
    WSMFpropertyDef(WSNhautoNumber, WSCbool, _hautoNumber);
    WSMFpropertyDef(WSNvautoNumber, WSCbool, _vautoNumber);
    WSMFpropertyDef(WSNsheetBackColor, short, _sheetBackColor);
    WSMFpropertyDef(WSNcellDefBackColor, short, _cellBackColor);
    WSMFpropertyDef(WSNcellDefTextColor, short, _cellTextColor);
    WSMFpropertyDef(WSNfixedBackColor, short, _fixedBackColor);
    WSMFpropertyDef(WSNfixedTextColor, short, _fixedTextColor);
    WSMFpropertyDef(WSNgridColor, short, _gridColor);

    WSMFpropertyDef(WSNdataSourceName, char*, _dataSource);
    WSMFpropertyDef(WSNdbTableName, char*, _tableName);
    WSMFpropertyDef(WSNdbItem, char*, _dbItem);
    WSMFpropertyDef(WSNsortItem1, char*, _dbSortItem1);
    WSMFpropertyDef(WSNsort1, WSCuchar, _dbSort1);
    WSMFpropertyDef(WSNsortItem2, char*, _dbSortItem2);
    WSMFpropertyDef(WSNsort2, WSCuchar, _dbSort2);
    WSMFpropertyDef(WSNsortItem3, char*, _dbSortItem3);
    WSMFpropertyDef(WSNsort3, WSCuchar, _dbSort3);
    WSMFpropertyDef(WSNfilter, char*, _dbFilter);
    WSMFpropertyDef(WSNsql, char*, _dbStmtString);
    WSMFpropertyDef(WSNdbCellAutoResize, WSCbool, _dbCellAutoResize);
    WSMFpropertyDef(WSNdbCellTitle, WSCbool, _dbCellTitle);

};
#endif // _WSCSHEET_H
