/***************************************************************************
                          menu.cpp  -  description
                             -------------------
    begin                : Tue Feb 29 2000
    copyright            : (C) 2000 by Michael Speck
    email                : 
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdlib.h>
#include <string.h>
#include "menu.h"

Menu::Menu(char *cap, int num)
	 : item_num(num)
{
	strcpy(caption, cap);
	//menu item pointer
	items = 0;
	items = new MenuItem*[item_num];
	for (int i = 0; i < item_num; i++)
		items[i] = 0;
	cur_item = 0;
	cur_id = 0;
}

Menu::~Menu()
{
	for (int i = 0; i < item_num; i++)
		if (items[i]) delete items[i];
	delete items;
}
	
int Menu::InsertItem(int i, MenuItem *mi)
{
	if (i >= 0 && i < item_num && mi != 0 && items[i] == 0) {
		items[i] = mi;
		return 0;
	}
	return 1;
}

void Menu::SetCurItem(int i)
{
	if (i >= 0 && i < item_num) {
		if (cur_item)
			cur_item->Enlight(0);
		cur_id = i;
		cur_item = items[i];
		cur_item->Enlight(1);
	}
}

MenuItem* Menu::CurItem()
{
	return cur_item;
}

MenuItem* Menu::Item(int i)
{
	if (i < 0 || i >= item_num) return 0;
	return items[i];
}

int Menu::KeyEvent(int code)
{
	switch (code) {
		case SDLK_UP:
			//previous item
			cur_item->Enlight(0);
			cur_id--; if (cur_id < 0) cur_id = item_num-1;
			while (items[cur_id]->Type() == ET_SEPARATOR) {
				cur_id--;
				if (cur_id < 0)
					cur_id = item_num-1;
			}
			cur_item = items[cur_id];
			cur_item->Enlight(1);
			return MR_CONTINUE;
		case SDLK_DOWN:
			//next item
			cur_item->Enlight(0);
			cur_id++; if (cur_id == item_num) cur_id = 0;
			while (items[cur_id]->Type() == ET_SEPARATOR) {
				cur_id++;
				if (cur_id == item_num) cur_id = 0;
			}
			cur_item = items[cur_id];
			cur_item->Enlight(1);
			return MR_CONTINUE;
		default:
			//item values changed?
			return cur_item->KeyEvent(code);
	}
}

void Menu::Update(int repaint)
{
	int i;
	for (i = 0; i < item_num; i++)
		items[i]->Update();
	if (repaint)
		for (i = 0; i < item_num; i++)
			items[i]->Refresh();
}

void Menu::Show(int repaint)
{
	int i;
	for (i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		items[i]->SetChanged(1);
		items[i]->Update();
	}
	if (repaint)
		for (i = 0; i < item_num; i++) {
			if (items[i] == 0) continue;
			items[i]->Refresh();
		}
}

void Menu::ClearState()
{
	for (int i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		items[i]->ClearAlpha();
    }		
}

void Menu::Hide(int repaint)
{
	int i;
	for (i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		items[i]->Hide();
		items[i]->ClearAlpha();
	}
	if (repaint)
		for (i = 0; i < item_num; i++) {
			if (items[i] == 0) continue;
			items[i]->Refresh();
		}
}

void Menu::Refresh()
{
	for (int i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		items[i]->Refresh();
	}
}

void Menu::Compute()
{
	for (int i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		items[i]->Compute();
	}
}

int Menu::ItemNum()
{
	return item_num;
}

void Menu::Prepare(int i)
{
	SetCurItem(i);
}

void Menu::NoBackgnd()
{
	for (int i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		items[i]->NoBackgnd();
	}
}

void Menu::MouseMotion(int mx, int my)
{
	for (int i = 0; i < item_num; i++) {
		if (items[i] == 0) continue;
		if (items[i]->OnItem(mx, my) &&
		    items[i] != cur_item &&
		    items[i]->Type() != ET_SEPARATOR &&
		    !(cur_item->Type() == ET_KEY && cur_item->Pos() == 0) ) {
		    // moved on a new item //
			cur_item->Enlight(0);
			cur_id = i;
			cur_item = items[cur_id];
			cur_item->Enlight(1);
		}
	}
}
