#include "afxadv.h"
#include "comdef.h"
#include "atlbase.h"

#if !defined(AFX_BWECTL_H__E1E72BA1_BEC3_11D3_8485_0080C890AEF9__INCLUDED_)
#define AFX_BWECTL_H__E1E72BA1_BEC3_11D3_8485_0080C890AEF9__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// BWECtl.h : Declaration of the CBWECtrl ActiveX Control class.

#define MAX_UNDO_LEVELS 8

#define MAX_WIDTH 128
#define MAX_HEIGHT 128
#define DEF_WIDTH 32
#define DEF_HEIGHT 32

#define MAX_DOT_SIZE 50
#define DEF_DOT_SIZE 16

#define MAX_DOT_GAP 10
#define DEF_DOT_GAP 4

#define COLOR_SEL_RECT 0x00FF0000 //selection rectangle color (bright blue)
#define COLOR_BK 0x00F0E5E5 //grid/background color (very light blue)
#define COLOR_DOT_OFF 0x00FFFFFF // dot is off (white)
#define COLOR_DOT_ON 0x00404040 // dot is on (very dark gray)
#define COLOR_DOT_ON_OVL 0x00E0A0A0 //dot is on on the overlay layer (blue-gray)
#define COLOR_DOT_ON_THRU_OVL 0x00A0A0A0 //dot is "on" on main layer and is visible thru overlay

#define COLOR_DOT_IN_SEL 0x004000

enum border_proximity{B_NIL,B_T,B_B,B_L,B_R,B_TL,B_TR,B_BL,B_BR,B_I,B_INI};
enum selection_states{SEL_IDLE,SEL_SELECTING,SEL_RESIZE_OR_DRAG,SEL_RESIZING,SEL_DRAGGING};

/////////////////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////////////////
// CBWECtrl : See BWECtl.cpp for implementation.

class CBWECtrl : public COleControl
{
	DECLARE_DYNCREATE(CBWECtrl)
	
// Constructor
public:
	CBWECtrl();
	
// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CBWECtrl)
	public:
	virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
	virtual void DoPropExchange(CPropExchange* pPX);
	virtual void OnResetState();
	//}}AFX_VIRTUAL

// Implementation
protected:
	unsigned char strToByte(CString* sptr, unsigned short *pos);
	BSTR byteToStr(unsigned char d);
	BOOL PreCreateWindow( CREATESTRUCT& cs ); //to define our own window style
	
	short BorderTest(CPoint point);
	void PasteOvl();
	void CopyOvl(bool cut,bool blonly);
	bool dotFromMouseCoord(CPoint point, short *px, short *py, bool gap);
	void drawSel(short x1, short y1, short x2, short y2, bool fl, bool rubber);
	~CBWECtrl();

	unsigned char m_dataArr[MAX_WIDTH*MAX_HEIGHT]; //keeps main graphic data
	unsigned char m_ovlArr[MAX_WIDTH*MAX_HEIGHT]; //keeps overlay data
	short m_sizeX,m_sizeY,m_dotSize,m_dotGap,m_fromX,m_fromY;
	BOOL m_selSet; //selection enabled, will show a square even when X1,Y1=X2,Y2
	BOOL m_noDot; //<<<<<<<<<<<<<<<<<<<<<<<
	BOOL m_panInProg,m_panLeft,m_panRight,m_panUp,m_panDown; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	BOOL m_btnState; //0- mouse button is not pressed, 1- pressed
	short m_selPosX1,m_selPosY1,m_selPosX2,m_selPosY2;
	short m_drawMode;
	long m_mouseX;
	char m_panDir;
	BOOL m_mode;
	short m_dragPtrOfsX,m_dragPtrOfsY; //drag pointer offset from left-top corner of sel rect
	short m_drawX,m_drawY; //remembers last dot that was drawn
	CRect CurrBounds; //to remember current bounds
	short m_selState; //selection state (see SEL_ constants)	
	short m_resizeDir; //resize direction (see B_ constants)
	CLIPFORMAT NEAR m_cfPrivate; //ID for a private temporary clipboard format
	short m_textAlignment; //0- left, 1-right, 2-middle

	// stuff below is used for undo/redo operations
	char m_undoPtr,m_undoCtr;
	struct undo{
		unsigned char m_dataArr[MAX_WIDTH*MAX_HEIGHT];
		unsigned char m_ovlArr[MAX_WIDTH*MAX_HEIGHT];
		short m_sizeX,m_sizeY;
		BOOL m_selSet;
		short m_selState;
		short m_selPosX1,m_selPosY1,m_selPosX2,m_selPosY2;
	}m_undo[MAX_UNDO_LEVELS];


	DECLARE_OLECREATE_EX(CBWECtrl)    // Class factory and guid
	DECLARE_OLETYPELIB(CBWECtrl)      // GetTypeInfo
	DECLARE_PROPPAGEIDS(CBWECtrl)     // Property page IDs
	DECLARE_OLECTLTYPE(CBWECtrl)		// Type name and misc status

// Message maps
	//{{AFX_MSG(CBWECtrl)
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnTimer(UINT nIDEvent);
	afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

// Dispatch maps
	//{{AFX_DISPATCH(CBWECtrl)
	afx_msg short GetSizeX();
	afx_msg void SetSizeX(short nNewValue);
	afx_msg short GetSizeY();
	afx_msg void SetSizeY(short nNewValue);
	afx_msg short GetDotSize();
	afx_msg void SetDotSize(short nNewValue);
	afx_msg short GetFromX();
	afx_msg void SetFromX(short nNewValue);
	afx_msg short GetFromY();
	afx_msg void SetFromY(short nNewValue);
	afx_msg short GetDotGap();
	afx_msg void SetDotGap(short nNewValue);
	afx_msg BOOL GetSelSet();
	afx_msg void SetSelSet(BOOL bNewValue);
	afx_msg short GetSelPosX1();
	afx_msg void SetSelPosX1(short nNewValue);
	afx_msg short GetSelPosY1();
	afx_msg void SetSelPosY1(short nNewValue);
	afx_msg short GetSelPosX2();
	afx_msg void SetSelPosX2(short nNewValue);
	afx_msg short GetSelPosY2();
	afx_msg void SetSelPosY2(short nNewValue);
	afx_msg short GetDrawMode();
	afx_msg void SetDrawMode(short nNewValue);
	afx_msg long GetMouseX();
	afx_msg void SetMouseX(long nNewValue);
	afx_msg BOOL GetMode();
	afx_msg void SetMode(BOOL bNewValue);
	afx_msg short GetTextAlignment();
	afx_msg void SetTextAlignment(short nNewValue);
	afx_msg void PaintSelection(short PaintMode);
	afx_msg void Escape();
	afx_msg BOOL Copy();
	afx_msg BOOL Paste();
	afx_msg BSTR GetData();
	afx_msg BOOL SetData(LPCTSTR str);
	afx_msg BSTR GetOvl();
	afx_msg BOOL SetOvl(LPCTSTR str);
	afx_msg void SetText(LPCTSTR str);
	afx_msg void MirrorSelection(BOOL hor);
	afx_msg void ImportPicture(LPPICTUREDISP pic);
	afx_msg void TightBound();
	afx_msg BOOL RotateSelection(short angle);
	afx_msg void Undo();
	afx_msg void ResetUndo();
	afx_msg void SaveUndo();
	afx_msg void Redo();
	afx_msg void Repaint();
	//}}AFX_DISPATCH
	DECLARE_DISPATCH_MAP()

	afx_msg void AboutBox();

// Event maps
	//{{AFX_EVENT(CBWECtrl)
	void FireMouseBtnUp(OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y)
		{FireEvent(eventidMouseBtnUp,EVENT_PARAM(VTS_XPOS_PIXELS  VTS_YPOS_PIXELS), x, y);}
	//}}AFX_EVENT
	DECLARE_EVENT_MAP()

// Dispatch and event IDs
public:
	void DisplCursor(short b);
	enum {
	//{{AFX_DISP_ID(CBWECtrl)
	dispidSizeX = 1L,
	dispidSizeY = 2L,
	dispidDotSize = 3L,
	dispidFromX = 4L,
	dispidFromY = 5L,
	dispidDotGap = 6L,
	dispidSelSet = 7L,
	dispidSelPosX1 = 8L,
	dispidSelPosY1 = 9L,
	dispidSelPosX2 = 10L,
	dispidSelPosY2 = 11L,
	dispidDrawMode = 12L,
	dispidMouseX = 13L,
	dispidMode = 14L,
	dispidTextAlignment = 15L,
	dispidPaintSelection = 16L,
	dispidEscape = 17L,
	dispidCopy = 18L,
	dispidPaste = 19L,
	dispidGetData = 20L,
	dispidSetData = 21L,
	dispidGetOvl = 22L,
	dispidSetOvl = 23L,
	dispidSetText = 24L,
	dispidMirrorSelection = 25L,
	dispidImportPicture = 26L,
	dispidTightBound = 27L,
	dispidRotateSelection = 28L,
	dispidUndo = 29L,
	dispidResetUndo = 30L,
	dispidSaveUndo = 31L,
	dispidRedo = 32L,
	dispidRepaint = 33L,
	eventidMouseBtnUp = 1L,
	//}}AFX_DISP_ID
	};
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_BWECTL_H__E1E72BA1_BEC3_11D3_8485_0080C890AEF9__INCLUDED)
