// ---------------------------------------------------------------------------
// 
//   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 <iostream>
using namespace std;

#include "../console/console.h"
using namespace Console;

#include "widgetbutton.h"
#include "widgetselectchild.h"

WidgetSelectChild::WidgetSelectChild(void) {
}

WidgetSelectChild::~WidgetSelectChild(void) {
}

void WidgetSelectChild::draw(void) {
	WidgetMultiParent::draw();
	
	// Get the right child to draw and focus it. This is probably
	// pretty slow and something I should feel horrible about putting
	// in the draw function, but whatever.
	for(std::map<std::string, int>::iterator i = radioToChildMap.begin(); i != radioToChildMap.end(); i++) {
		
		WidgetButton *button = dynamic_cast<WidgetButton*>(widgetGetByUID((*i).first));
		
		if(button && button->getToggleValue()) {
			
			// Found an active radio button in our list.
			
			if((*i).second == focusedChild) {
				
				// The button already corresponds to the correct child.
				// We're done here.
			
			} else {
			
				// Need to focus this child.
				switchFocus((*i).second);
			
			}
		
			break;
		}
	}	
	
	// Draw focused child.
	Widget *child = getFocusedChild();
	if(child) {
		child->draw();
	}
}

float WidgetSelectChild::getMinHeight(void) {
	Widget *child = getFocusedChild();
	float childSize = child ? child->getMinHeight() : 0;
	float mySize    = WidgetMultiParent::getMinHeight();
	return mySize > childSize ? mySize : childSize;
}

float WidgetSelectChild::getMinWidth(void) {
	Widget *child = getFocusedChild();
	float childSize = child ? child->getMinWidth() : 0;
	float mySize    = WidgetMultiParent::getMinWidth();
	return mySize > childSize ? mySize : childSize;
}

void WidgetSelectChild::setWidth(float newWidth) {
	WidgetMultiParent::setWidth(newWidth);
	Widget *child = getFocusedChild();
	if(child) child->setWidth(newWidth);
}

void WidgetSelectChild::setHeight(float newHeight) {
	WidgetMultiParent::setHeight(newHeight);
	Widget *child = getFocusedChild();
	if(child) child->setHeight(newHeight);
}

bool WidgetSelectChild::handleEvent(const WidgetEvent *event) {
	bool ret = WidgetMultiParent::handleEvent(event);
	
	if(ret) {
		// Any focus event can cause us to possibly switch to a new
		// child, which can be a different size.
		if(	event->type == WIDGETEVENT_FOCUSACCEPT ||
			event->type == WIDGETEVENT_FOCUSACCEPT_BACK ||
			event->type == WIDGETEVENT_FOCUSENTER ||
			event->type == WIDGETEVENT_FOCUSLEAVE ||
			event->type == WIDGETEVENT_FOCUSNEXT ||
			event->type == WIDGETEVENT_FOCUSPREV) {
				
			markSizeDirty();
		}
		
		if(event->type == WIDGETEVENT_FOCUSNEXT || event->type == WIDGETEVENT_FOCUSPREV) {
			
			// Mark all radio buttons except the selected one as inactive.
			// Oh. It'll help if they're all in the same radio group,
			// and probably explode horribly if they aren't.

			for(std::map<std::string, int>::iterator i = radioToChildMap.begin(); i != radioToChildMap.end(); i++) {
				
				if((*i).second == focusedChild) {
					
					// Found the button that goes with this child.

					WidgetButton *button = dynamic_cast<WidgetButton*>(widgetGetByUID((*i).first));
					
					if(button) {
						button->setToggleValue(true);
					}
				}
				
			}	
			
		}
		
		return true;
	}
	
	// Mouse events and other crap needs to go to the focused child.
	Widget *child = getFocusedChild();
	if(child) {
		ret = child->handleEvent(event);
	}
	
	return ret;
}

void WidgetSelectChild::switchFocus(int newFocus) {
	WidgetMultiParent::switchFocus(newFocus);
	markSizeDirty();
}

void WidgetSelectChild::mapRadioToChild(Widget *radio, Widget *child) {
	
	if(!radio) return;
	
	// Find the child in the list of children.
	int childSlot = -1;
	for(unsigned int i = 0; i < children.size(); i++) {
		if(children[i] == child) {
			childSlot = (int)i;
			break;
		}
	}
	
	if(childSlot != -1) {
		radioToChildMap[radio->getUID()] = childSlot;
	} else {
		radioToChildMap.erase(radio->getUID());
	}
}

void WidgetSelectChild::clearRadioToChildMaps(void) {
	radioToChildMap.clear();
}

