#ifndef _OVERRIDDENCONTROL_H_
#define _OVERRIDDENCONTROL_H_ 1

#pragma once

#if _MINICAD_
#include "DrawPad.X.h"
#endif

#include "GSGeometry.h"
#include "ExternMisc.h"

void InvalidateCtrl(int, int);
void RefreshCtrl(int, int);

class OverriddenLayoutControl {
#if GS_WIN
	friend LRESULT CALLBACK OverriddenLayoutControlProc(HWND controlHWND, UINT message, WPARAM wParam, LPARAM lParam/*, int dialogID, int componentID*/);
#else
	friend void OverriddenLayoutControlProc(long message, void *ioParam, void *pane, int dialogID, int componentID);
	friend OSStatus MouseTrackingFunc(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData);
#endif

  public:
	OverriddenLayoutControl();
	virtual ~OverriddenLayoutControl() { }
  
	void Attach(int dlogID, int controlID, bool wantDrawPad);	// to be done during kSetupMessage
	void Detach();												// to be done during kSetdownMessage

	virtual void OnDraw() {}
	virtual void OnLButtonDown(int x, int y) {}
	virtual void OnLButtonUp(int x, int y) {}
	virtual void OnRButtonDown(int x, int y) {}
	virtual void OnRButtonUp(int x, int y) {}
	virtual void OnMButtonDown(int x, int y) {}
	virtual void OnMButtonUp(int x, int y) {}
	virtual void OnMouseEnter() {}
	virtual void OnMouseLeave() {}

	virtual void OnMouseWheel(int x, int y, int amount) {}

	virtual void OnMouseMove(int x, int y) {}
	virtual void OnInit() {}
	virtual void OnDetatch() {}
	
#if _MINICAD_
	TDrawPad* fpDrawPad;
#endif

  private:
	int fDlogID, fControlID;
	bool fInitialized;
	bool fUsesDrawPad;
	bool fDrawPadInitialized;
	void *fIdentifier;  // on win = HWND of control, on mac = LPane *
	void SetupDraw();
	void FinishDraw();

	bool mouseEntered;

#if !GS_WIN
	bool initialMouseMove;
	int initialMouseMoveX, initialMouseMoveY;
#endif

  public:
	#if GS_WIN
		HWND GetHWND() { return (HWND) fIdentifier; }
	#endif

	int GetDialogID() { return fDlogID; }
	int GetControlID() { return fControlID; }
	void* GetIdentifier() { return fIdentifier; }
	
	void Invalidate() { ::InvalidateCtrl(fDlogID, fControlID); }
	void Refresh() { ::RefreshCtrl(fDlogID, fControlID); } 

	Sint16 LocalX(Sint16 x) { return x + fDrawRect.left; }
	Sint16 LocalY(Sint16 y) { return y + fDrawRect.top;  }
	ViewRect LocalR(const ViewRect &r) {
		ViewRect local;
		local.left = r.left + fDrawRect.left;
		local.top = r.top + fDrawRect.top;
		local.right = r.right + fDrawRect.left;
		local.bottom = r.bottom + fDrawRect.top;
		return local;
	}
	ViewRect LocalR(int l, int t, int r, int b) {
		return LocalR(ViewRect(l,t,r,b));
	}

		ViewRect GetDrawRect() { ASSERTN(kDaveD | kBWilliams, fDrawRectInitialized); return fDrawRect; }

		void SetDrawRect(const ViewRect& inRect) {
			fDrawRect = inRect;
			fDrawRectInitialized = true;
		}

	protected:
		bool fDrawRectInitialized;
		ViewRect fDrawRect;
};


inline GSColor MakeGSColor(Byte r, Byte g, Byte b) {
	GSColor c;
	c.Set8(r, g, b);
	return c;
}

inline GSColor MakeGSColor(int sysColor) {

	TRGBColor maccolor;
#if GS_WIN
	GetSysColor(sysColor, &maccolor);
#else
	long qdColor;
	GetSysColor(sysColor, &maccolor, &qdColor);
#endif

	GSColor c;
	c.Set16(maccolor.red>>8, maccolor.green>>8, maccolor.blue>>8);
	return c;
}


#endif	// _OVERRIDDENCONTROL_H_
