/*
 * Copyright (c) 2001, 2002, 2003 Gary R. Van Sickle.
 * Copyright (c) 2005-2006 Tom N Harris.
 *
 *     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.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
 * Written by Tom N Harris <telliamed@whoopdedo.org>
 *
 */

#ifndef SETUP_WINDOW_H
#define SETUP_WINDOW_H

// This is the header for the Window class.  It serves both as a window class
// in its own right and as a base class for other window-like classes (e.g. PropertyPage,
// PropSheet).

#include <vector>

#include "win32.h"
#include "cString.h"

namespace Setup
{

class Window
{
	static ATOM WindowClassAtom;
	static HINSTANCE AppInstance;

	virtual bool registerWindowClass();
protected:
	static LRESULT CALLBACK FirstWindowProcReflector(HWND hwnd, UINT uMsg,
							 WPARAM wParam,
							 LPARAM lParam);
private:
	static LRESULT CALLBACK WindowProcReflector(HWND hwnd, UINT uMsg,
						    WPARAM wParam, LPARAM lParam);

	// Our Windows(tm) window handle.
	HWND m_windowHandle;

	Window* m_parent;

	// FIXME: replace with <vector> when we get a chance.
	typedef std::vector<HFONT> FontList;
	FontList m_fonts;

protected:
	void setHWND(HWND h)
		{ m_windowHandle = h; };
	void setParent(Window* aParent)
		{ m_parent = aParent; }

public:
	Window();
	virtual ~Window();

	static void SetAppInstance(HINSTANCE h)
	{
		// This only has to be called once in the entire app, before
		// any Windows are created.
		AppInstance = h;
	};
	static HINSTANCE GetAppInstance()
	{
		return AppInstance;
	};

	virtual bool messageLoop();
	virtual LRESULT windowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);

	virtual bool create(Window * Parent = NULL,
			    DWORD Style =
				  WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN);
	virtual void init();
	void show(int State);

	HWND getHWND() const
	{
		// Ideally this could be hidden from the user completely.
		return m_windowHandle;
	};
	HINSTANCE getInstance() const
	{
		return AppInstance;
	};

	Window * getParent() const
	{
		return m_parent;
	};
	HWND getDlgItem(int id) const
	{
		return ::GetDlgItem(getHWND(), id);
	};
	bool setDlgItemFont(int id, const TCHAR * fontname, int Pointsize,
			    int Weight = FW_NORMAL, bool Italic = false, 
			    bool Underline = false, bool Strikeout = false);

	UINT isButtonChecked(int nIDButton) const;

	void postMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0);

	virtual bool onMessageApp(UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		// Not processed by default.  Override in derived classes to
		// do something with app messages if you need to.
		return false;
	};

	virtual bool onMessageCmd(int id, HWND hwndctl, UINT code)
	{
		// Not processed by default.  Override in derived classes to
		// do something with command messages if you need to.
		return false;
	};

	RECT getWindowRect() const;
	RECT getClientRect() const;

	RECT getDlgItemRect(int id) const;


	// Center the window on the parent, or on screen if no parent.
	void centerWindow();

	// Reposition the window
	bool moveWindow(long x, long y, long w, long h, bool Repaint = true);
	bool moveWindow(const RECTWrapper &r, bool Repaint = true);

	// Set the title of the window.
	void setWindowText(const String & s);
	void setDlgItemText(int id, const String & s);
	String getDlgItemText(int id);

	RECT screenToClient(const RECT &r) const;

	void refresh();
};

};

#endif /* SETUP_WINDOW_H */
