/*
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#pragma warning (disable: 4786)

#define STRICT
#include <Windows.h>
#include <string>
#include <map>
#include <list>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include "WinOnly.h"
#include "WinBe.h"
#include "NativeApplication.h"

using namespace winBe;


NativeApplication NativeApplication::appInstance;


// constructor
NativeApplication::NativeApplication ()
{
}


// destructor
NativeApplication::~NativeApplication ()
{
	windowLookup.clear ();
	viewLookup.clear ();
}


// run
int NativeApplication::run ()
{
	return main (0, 0);
}


// initialize
void NativeApplication::initialize (HINSTANCE hInstance, HINSTANCE hPrevInstance, const char* lpCmdLine)
{
	this->hInstance = hInstance;
	if (!hPrevInstance) {
		WNDCLASS wc;

		wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc = reinterpret_cast<WNDPROC>(NativeWindowWndProc);
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 4;
		wc.hInstance = hInstance;
		wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
		wc.hCursor = LoadCursor (NULL, IDC_ARROW);
		wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
		wc.lpszMenuName = NULL;
		wc.lpszClassName = "BWindow";

		RegisterClass (&wc);

		wc.lpfnWndProc = reinterpret_cast<WNDPROC>(NativeViewWndProc);
		wc.lpszClassName = "BView";

		RegisterClass (&wc);
	}
}


// instance
HINSTANCE NativeApplication::getHINSTANCE ()
{
	return hInstance;
}


// findWindow
NativeWindow* NativeApplication::findWindow (BWindow* window)
{
	NativeWindowLookup::iterator i = windowLookup.find (window);
	return i != windowLookup.end () ? (*i).second.get () : 0;
}


// addWindow
NativeWindow* NativeApplication::addWindow (BWindow* window)
{
	NativeWindowPtr nativeWindow = NativeWindowPtr (new NativeWindow (window));
	windowLookup.insert (std::make_pair (window, nativeWindow));
	return nativeWindow.get ();
}


// deleteWindow
void NativeApplication::deleteWindow (BWindow* window)
{
	NativeWindowLookup::iterator i = windowLookup.find (window);
	if (i != windowLookup.end ())
		windowLookup.erase (i);
}


// getWindowList
WindowList NativeApplication::getWindowList ()
{
	WindowList windowList;

	for (NativeWindowLookup::iterator i = windowLookup.begin (); i != windowLookup.end (); ++i)
		windowList.push_back ((*i).first);

	return windowList;
}


// findView
NativeView* NativeApplication::findView (BView* view)
{
	NativeViewLookup::iterator i = viewLookup.find (view);
	return i != viewLookup.end () ? (*i).second.get () : 0;
}


// addView
NativeView* NativeApplication::addView (BView* view, NativeWindow* window)
{
	NativeViewPtr nativeView (new NativeView (view, window));
	viewLookup.insert (std::make_pair (view, nativeView));
	return nativeView.get ();
}


// deleteView
void NativeApplication::deleteView (BView* view)
{
	NativeViewLookup::iterator i = viewLookup.find (view);
	if (i != viewLookup.end ())
		viewLookup.erase (i);
}
