/// Copyright (c) 2010 Ruben Penalva. All rights reserved.
/// Redistribution and use in source and binary forms, with or without modification, 
/// are permitted provided that the following conditions are met:
///    1. Redistributions of source code must retain the above copyright notice, this 
///    list of conditions and the following disclaimer.
///    2. Redistributions in binary form must reproduce the above copyright notice,
///    this list of conditions and the following disclaimer in the documentation and/or
///    other materials provided with the distribution.
///    3. The name of the author may not be used to endorse or promote products derived
///    from this software without specific prior written permission.
///
/// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
/// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
/// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
/// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
/// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
/// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
/// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "Window.h"

#include "UnicodeString.h"
#include "MouseEvent.h"

#include <windows.h>

using namespace TestFrameWork;

Window::Window(const std::wstring windowTitle, 
			   ITabVector tabs, IWindowListener* listener,
			   UserEventQueue& eventQueue)	:	m_tabs(tabs), m_listener(listener), m_eventQueue(eventQueue)
{
	CreateUI(windowTitle);

	show();
}

Window::~Window(void)
{
}

HDC Window::GetRenderCanvasContext(void) const
{
	return m_renderCanvasContext;
}

size_t Window::GetWidth(void) const
{
	return 800;
}

size_t Window::GetHeight(void) const
{
	return 600;
}

void Window::closeEvent(QCloseEvent* event)
{
	m_listener->OnClose();
	
	event->accept();
}	

void Window::mouseMoveEvent(QMouseEvent* event)
{
	UpdateMouseState(event);

	m_eventQueue.Push(MouseEventPtr(new MouseEvent(m_mouseState)));
}

void Window::wheelEvent(QWheelEvent* event)
{
	UpdateMouseState(event);

	m_eventQueue.Push(MouseEventPtr(new MouseEvent(m_mouseState)));
}

void Window::CreateUI(const std::wstring& windowTitle)
{
	setObjectName(QString::fromUtf8("Form"));
	resize(1037, 618);
	setMinimumSize(QSize(1037, 618));
	setMaximumSize(QSize(1037, 618));

	QHBoxLayout* horizontalLayout(new QHBoxLayout(this));
	horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));

	QFrame* render(new QFrame(this));
	m_renderCanvasContext = render->getDC();
	render->setObjectName(QString::fromUtf8("Render"));
	render->setEnabled(true);
	render->setMinimumSize(QSize(800, 600));
	render->setMaximumSize(QSize(800, 600));
	render->setSizeIncrement(QSize(0, 0));
	render->setLayoutDirection(Qt::LeftToRight);
	render->setFrameShape(QFrame::Panel);
	render->setFrameShadow(QFrame::Sunken);

	horizontalLayout->addWidget(render);

	QWidget* settings(new QWidget(this));
	settings->setObjectName(QString::fromUtf8("Settings"));
	QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
	sizePolicy.setHorizontalStretch(1);
	sizePolicy.setVerticalStretch(0);
	sizePolicy.setHeightForWidth(settings->sizePolicy().hasHeightForWidth());
	settings->setSizePolicy(sizePolicy);
	settings->setMinimumSize(QSize(213, 600));
	settings->setMaximumSize(QSize(213, 600));

	QGroupBox* groupBox(new QGroupBox(settings));
	groupBox->setObjectName(QString::fromUtf8("groupBox"));
	groupBox->setGeometry(QRect(10, 510, 201, 91));

	QLabel* label(new QLabel(groupBox));
	label->setObjectName(QString::fromUtf8("label"));
	label->setGeometry(QRect(10, 20, 121, 16));

	QLabel* label_2(new QLabel(groupBox));
	label_2->setObjectName(QString::fromUtf8("label_2"));
	label_2->setGeometry(QRect(10, 40, 181, 16));

	QLabel* label_3(new QLabel(groupBox));
	label_3->setObjectName(QString::fromUtf8("label_3"));
	label_3->setGeometry(QRect(10, 60, 141, 20));

	QTabWidget* tabWidget(new QTabWidget(settings));
	tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
	tabWidget->setGeometry(QRect(10, 0, 201, 501));

	horizontalLayout->addWidget(settings);

	setWindowTitle(QString(ConvertUTF16ToUTF8(windowTitle).c_str()));
	groupBox->setTitle(QApplication::translate("Form", "Contact", 0, QApplication::UnicodeUTF8));
	label->setText(QApplication::translate("Form", "Ruben Penalva", 0, QApplication::UnicodeUTF8));
	label_2->setText(QApplication::translate("Form", "ruben.penalva@rpenalva.com", 0, QApplication::UnicodeUTF8));
	label_3->setText(QApplication::translate("Form", "http://www.rpenalva.com", 0, QApplication::UnicodeUTF8));
	
	tabWidget->setCurrentIndex(0);

	QMetaObject::connectSlotsByName(this);

	AddSettingsTabs(tabWidget);
}

void Window::AddSettingsTabs(QTabWidget* tabWidget) 
{
	size_t tabsCount = m_tabs.size();
	for (size_t i = 0; i < tabsCount; ++i)
	{
		QWidget* tab = m_tabs[i]->GetWidget();
		tab->setStyleSheet(QString::fromUtf8("background-color: rgb(240, 240, 240);"));
		tabWidget->addTab(tab, QString());

		tabWidget->setTabText(tabWidget->indexOf(tab),tab->objectName());
	}
}

void Window::UpdateMouseState(QMouseEvent* event)
{
	m_mouseState.NextPosition(event->x(), event->y());

	Qt::MouseButtons buttons(event->buttons());

	if ((buttons & Qt::LeftButton) == Qt::LeftButton)
	{
		m_mouseState.m_button = Left;
		m_mouseState.m_pressed = true;
	}
	else if ((buttons & Qt::RightButton) == Qt::RightButton)
	{
		m_mouseState.m_button = Right;
		m_mouseState.m_pressed = true;
	}
	else if((buttons & Qt::MidButton) == Qt::MidButton)
	{
		m_mouseState.m_button = Middle;
		m_mouseState.m_pressed = true;
	}
	else
	{
		m_mouseState.m_button = None;
		m_mouseState.m_pressed = false;
	}
}

void Window::UpdateMouseState(QWheelEvent* event)
{
	m_mouseState.m_button = Wheel;
	m_mouseState.m_delta = event->delta();
}