// ---------------------------------------------------------------------------
// 
//   Lily Engine alpha
// 
//   Copyright (c) 2010 Clifford Jolly
//     http://cliffjolly.com
//     cliff@cliffjolly.com
// 
// ---------------------------------------------------------------------------
// 
//   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
// -------------------------- END HEADER -------------------------------------

#include "../hacks/winhacks.h"

#include <iostream>
using namespace std;

#include <GL/gl.h>

#include "widgetpaddedbox.h"
#include "widgettext.h"

#include "../3rdparty/tinyxml/tinyxml.h"

WidgetPaddedBox::WidgetPaddedBox(void) : WidgetSingleParent() {
	setPadding(8);
	child = NULL;
}

WidgetPaddedBox::WidgetPaddedBox(TiXmlElement *xml) : WidgetSingleParent(xml) {
	float defaultPadding = 8;
	xml->QueryFloatAttribute("padding", &defaultPadding);
	setPadding(defaultPadding);
	
	xml->QueryFloatAttribute("left", &leftPadding);
	xml->QueryFloatAttribute("right", &rightPadding);
	xml->QueryFloatAttribute("top", &topPadding);
	xml->QueryFloatAttribute("bottom", &bottomPadding);
	
	setWidth(width);
	setHeight(height);
}

WidgetPaddedBox::~WidgetPaddedBox(void) {
}

void WidgetPaddedBox::setPadding(float allPadding) {
	setPaddingTop(allPadding);
	setPaddingBottom(allPadding);
	setPaddingLeft(allPadding);
	setPaddingRight(allPadding);
}

void WidgetPaddedBox::setPaddingTop(float padding) {
	topPadding = padding;
}

void WidgetPaddedBox::setPaddingBottom(float padding) {
	bottomPadding = padding;
}

void WidgetPaddedBox::setPaddingLeft(float padding) {
	leftPadding = padding;
}

void WidgetPaddedBox::setPaddingRight(float padding) {
	rightPadding = padding;
}

float WidgetPaddedBox::getPaddingTop(void) {
	return topPadding;
}

float WidgetPaddedBox::getPaddingBottom(void) {
	return bottomPadding;
}

float WidgetPaddedBox::getPaddingLeft(void) {
	return leftPadding;
}

float WidgetPaddedBox::getPaddingRight(void) {
	return rightPadding;
}

void WidgetPaddedBox::draw(void) {
	WidgetSingleParent::draw();
	
	if(child) {
		glPushMatrix();

		glTranslatef(leftPadding, topPadding, 0);

		pushClipArea(0, 0, 
			width - (leftPadding + rightPadding), height - (topPadding + bottomPadding));

		child->draw();
		
		popClipArea();
		
		glPopMatrix();
	}
}

float WidgetPaddedBox::getMinHeight(void) {
	float realMinHeight = topPadding + bottomPadding;
	float widgetMinHeight = WidgetSingleParent::getMinHeight();
	if(child) realMinHeight += child->getMinHeight();	
	return realMinHeight > widgetMinHeight ? realMinHeight : widgetMinHeight;
}

float WidgetPaddedBox::getMinWidth(void) {
	float realMinWidth = leftPadding + rightPadding;
	float widgetMinWidth = WidgetSingleParent::getMinWidth();
	if(child) realMinWidth += child->getMinWidth();
	return realMinWidth > widgetMinWidth ? realMinWidth : widgetMinWidth;
}

void WidgetPaddedBox::setWidth(float newWidth) {
	WidgetSingleParent::setWidth(newWidth);
	float childWidth = width - (leftPadding + rightPadding);
	if(child) child->setWidth(childWidth);
}

void WidgetPaddedBox::setHeight(float newHeight) {
	WidgetSingleParent::setHeight(newHeight);
	float childHeight = height - (topPadding + bottomPadding);
	if(child) child->setHeight(childHeight);
}

bool WidgetPaddedBox::handleEvent(const WidgetEvent *event) {

	bool ret = WidgetSingleParent::handleEvent(event);

	float oldOffsetX = debugDrawOffsetX;
	float oldOffsetY = debugDrawOffsetY;
	
	// Copy the whole event so whatever we don't change is sane.
	WidgetEvent shiftedEvent = *event;
	
	if(event->type == WIDGETEVENT_MOUSEMOTION ||
		event->type == WIDGETEVENT_MOUSEDOWN ||
		event->type == WIDGETEVENT_MOUSEUP) {
		
		shiftedEvent.mouse.x -= leftPadding;
		shiftedEvent.mouse.y -= topPadding;
		debugDrawOffsetX += leftPadding;
		debugDrawOffsetY += topPadding;
	
		if(child) ret |= child->handleEvent(&shiftedEvent);

	} else {

		// I don't know what this is. Just pass it along.
		if(child) ret |= child->handleEvent(&shiftedEvent);
		
	}	
	
	debugDrawOffsetX = oldOffsetX;
	debugDrawOffsetY = oldOffsetY;
	
	return ret;
}

