/*Title:      mjbWorld
Copyright (c) 1998-2002 Martin John Baker

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

For information about the GNU General Public License see http://www.gnu.org/

If you would like to contact me, my e-mail is martinb@martinb.com and my
website is http://www.martinb.com/
*/

#pragma once
#include "resource.h"       // main symbols
#include <atlctl.h>
#include "mjbogl.h"
#include "_ImjboglCtlEvents_CP.h"

#include <iostream>
using namespace std;

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
#pragma warning(disable : 4100)

// CmjboglCtl
class ATL_NO_VTABLE CmjboglCtl : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CStockPropImpl<CmjboglCtl, ImjboglCtl>,
	public IPersistStreamInitImpl<CmjboglCtl>,
	public IOleControlImpl<CmjboglCtl>,
	public IOleObjectImpl<CmjboglCtl>,
	public IOleInPlaceActiveObjectImpl<CmjboglCtl>,
	public IViewObjectExImpl<CmjboglCtl>,
	public IOleInPlaceObjectWindowlessImpl<CmjboglCtl>,
	public IConnectionPointContainerImpl<CmjboglCtl>,
	public CProxy_ImjboglCtlEvents<CmjboglCtl>, 
	public IDataObjectImpl<CmjboglCtl>,
	public IProvideClassInfo2Impl<&CLSID_mjboglCtl, &__uuidof(_ImjboglCtlEvents), &LIBID_mjboglLib>,
	public CComCoClass<CmjboglCtl, &CLSID_mjboglCtl>,
	public CComControl<CmjboglCtl>
{
public:
	HDC my_hdc;
	RECT my_rc;

	BOOL m_bActive;
	BOOL m_bMouseCaptured;
	int m_xPos;
	int m_yPos;
	HGLRC m_hrc;
	HPALETTE m_hPal;
	LOGPALETTE *m_pPal;
	WORD joyposX;
	WORD joyposY;
	WORD joyposZ;

	CmjboglCtl();
	~CmjboglCtl();

DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE | 
	OLEMISC_CANTLINKINSIDE | 
	OLEMISC_INSIDEOUT | 
	OLEMISC_ACTIVATEWHENVISIBLE | 
	OLEMISC_SETCLIENTSITEFIRST
)

DECLARE_REGISTRY_RESOURCEID(IDR_MJBOGLCTL)

BEGIN_COM_MAP(CmjboglCtl)
	COM_INTERFACE_ENTRY(ImjboglCtl)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(IViewObjectEx)
	COM_INTERFACE_ENTRY(IViewObject2)
	COM_INTERFACE_ENTRY(IViewObject)
	COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
	COM_INTERFACE_ENTRY(IOleInPlaceObject)
	COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
	COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
	COM_INTERFACE_ENTRY(IOleControl)
	COM_INTERFACE_ENTRY(IOleObject)
	COM_INTERFACE_ENTRY(IPersistStreamInit)
	COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
	COM_INTERFACE_ENTRY(IConnectionPointContainer)
	COM_INTERFACE_ENTRY(IDataObject)
	COM_INTERFACE_ENTRY(IProvideClassInfo)
	COM_INTERFACE_ENTRY(IProvideClassInfo2)
END_COM_MAP()

BEGIN_PROP_MAP(CmjboglCtl)
	PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
	PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
	PROP_ENTRY("Text", DISPID_TEXT, CLSID_NULL)
	// Example entries
	// PROP_ENTRY("Property Description", dispid, clsid)
	// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

BEGIN_CONNECTION_POINT_MAP(CmjboglCtl)
	CONNECTION_POINT_ENTRY(__uuidof(_ImjboglCtlEvents))
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(CmjboglCtl)
	MESSAGE_HANDLER(WM_CREATE, OnCreate)
	MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
	MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
	MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
	MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
	MESSAGE_HANDLER(WM_SIZE, OnSize)
	MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
	CHAIN_MSG_MAP(CComControl<CmjboglCtl>)
	DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

// IViewObjectEx
	DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

// ImjboglCtl
public:
	HRESULT OnDraw(ATL_DRAWINFO& di);
	BOOL bSetupPixelFormat(HDC hdc);
	LRESULT OnJoyMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnJoyZMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	void CreateContext(HDC hdc, RECT& rc);
	void CreateRGBPalette(HDC hdc);
	unsigned char ComponentFromIndex(int i, UINT nbits, UINT shift);
	CComBSTR m_bstrText;
	void OnTextChanged()
	{
		ATLTRACE(_T("OnTextChanged\n"));
	}

	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}
	
	void FinalRelease() 
	{
	}
	STDMETHOD(SceneGraphBegin)(void);
	STDMETHOD(SceneGraphEnd)(void);
	STDMETHOD(mglBegin)(USHORT i);
	STDMETHOD(mglEnd)(void);
	STDMETHOD(mglColor3f)(FLOAT r, FLOAT g, FLOAT b);
	STDMETHOD(mglNormal3f)(FLOAT x, FLOAT y, FLOAT z);
	STDMETHOD(mglTexCoord2f)(FLOAT u, FLOAT v);
	STDMETHOD(mglVertex3d)(DOUBLE x, DOUBLE y, DOUBLE z);
	STDMETHOD(mglPushMatrix)(void);
	STDMETHOD(mglPopMatrix)(void);
	STDMETHOD(mglTranslated)(DOUBLE x, DOUBLE y, DOUBLE z);
	STDMETHOD(mglRotated)(DOUBLE a, DOUBLE x, DOUBLE y, DOUBLE z);
	STDMETHOD(mglScaled)(DOUBLE x, DOUBLE y, DOUBLE z);
	STDMETHOD(mglEnable)(USHORT i);
	STDMETHOD(mglDisable)(USHORT i);
	STDMETHOD(mglEnableClientState)(USHORT i);
	STDMETHOD(mglDisableClientState)(USHORT i);
	STDMETHOD(mglColorMaterial)(USHORT i1,USHORT i2);
	STDMETHOD(mglMaterialf)(USHORT i1, USHORT i2, FLOAT f1, FLOAT f2, FLOAT f3, FLOAT f4);
	STDMETHOD(mglLightf)(USHORT i1, USHORT i2, FLOAT f1, FLOAT f2, FLOAT f3, FLOAT f4);
	STDMETHOD(SceneGraphInit)(FLOAT a, FLOAT n, FLOAT f);
	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
};

OBJECT_ENTRY_AUTO(__uuidof(mjboglCtl), CmjboglCtl)
