#include <curses.h>
#include <string>

#ifndef _MENU_H_
#define _MENU_H_ 

class Menu
{
	public:
		Menu(std::string name, char trigger, std::string *items, int itemCount);
		void selectNextItem(); 
		void selectPrevItem(); 

		int startX, startY; 
		std::string name; 
		char trigger;	
		int selectedItem = 0; // alyas have the first one selected
		std::string *items;
		int itemCount=0; 
};

Menu::Menu(std::string name, char trigger, std::string *items, int itemCount)
{
	this->name = name; 
	this->trigger = trigger; 
	this->items = items;
	this->itemCount = itemCount;
}

void Menu::selectNextItem()
{
	selectedItem ++;
	if(selectedItem >= itemCount)
	{
		selectedItem = 0; 
	}
}

void Menu::selectPrevItem()
{
	selectedItem--;
	if(selectedItem  < 0)
	{
		selectedItem = itemCount-1; 
	}
}

class MenuBar
{
	public: 
		MenuBar(WINDOW * win, Menu * menus, int menuCnt);
		void draw(); 
		void handleTrigger(char trigger);
		void reset(); 
		void drawMenu(Menu menu, int currIndex);  
		void drawMenuItems(Menu menu); 

		WINDOW * win;
		WINDOW * menuwin;
		Menu * menus; 
		int menuCnt; 
		int i =0;	
		int selected_menu = 90; 
		int start_pos = 0; 
		std::string name; 
};

MenuBar::MenuBar(WINDOW * win, Menu * menus, int menuCnt)
{
	this->win = win;
	this->menus = menus; 
	this->menuCnt = menuCnt; 
	int currPos = 2; 

	//Initialize the menu window
	int xMax, yMax, xBeg, yBeg = 0; 
	getmaxyx(win, yMax, xMax); 
	getbegyx(win, yBeg, xBeg); 
	
	menuwin = newwin(yMax-2, xMax-2, yBeg+1, xBeg+1);
	keypad(menuwin, true); 
	wrefresh(menuwin); 

	for(i = 0; i < menuCnt ; i ++) 
	{
		this->menus[i].startX = currPos; 
		currPos += this->menus[i].name.length() + 1; 
	}
}

void MenuBar::draw()
{
	for(i = 0; i < menuCnt ; i ++) 
	{
		drawMenu(menus[i], i);	
	}
	selected_menu = -1; 
}

void MenuBar::drawMenu(Menu menu,int currIndex) 
{
	start_pos = menu.startX;
	name = menu.name; 
	if(currIndex == selected_menu)
	{
		wattron(win, A_STANDOUT);
	}
	mvwprintw(win, 0, start_pos, name.c_str());
	wattroff(win, A_STANDOUT);
	wrefresh(win);

	int ch = 0; 
	
	drawMenuItems(menu);
	
	while(currIndex == selected_menu && (ch = wgetch(menuwin)))
	{
		switch(ch) 
		{
			case KEY_UP: 
				menu.selectPrevItem(); 
				break; 
			case KEY_DOWN: 
				menu.selectNextItem(); 
				break; 
			default:
				currIndex = -1;
				break;
		}
		drawMenuItems(menu);
	}
	werase(menuwin);
	wrefresh(menuwin);
	reset();
}

void MenuBar::drawMenuItems(Menu menu) 
{
	int yMax, xMax; 
	getmaxyx(menuwin, yMax, xMax); 

	for(i=0; i < menu.itemCount ; i ++)
	{
	  mvwprintw(menuwin,i,0,menu.items[i].c_str());
	  if(menu.selectedItem == i)
	  {
		  //if selected change to color pair 1
		mvwchgat(menuwin,i,0,xMax,A_NORMAL,1, NULL);
	  }
	  else 
	  {
		  // Not selected but we still want it to be reversed
		mvwchgat(menuwin,i,0,xMax,A_STANDOUT,0, NULL);
	  }
	}
}

void MenuBar::reset()
{
	for(i = 0; i < menuCnt ; i ++) 
	{
		start_pos = this->menus[i].startX;
		name = this->menus[i].name; 
		mvwprintw(win, 0, start_pos, name.c_str());
	}
	wrefresh(win);
}

void MenuBar::handleTrigger(char trigger)
{
	for(i = 0; i < menuCnt ; i ++) 
	{
		if(trigger == this->menus[i].trigger)
		{
			selected_menu = i; 
		}
	}
}

#endif
