#include <string.h>
#include <panel.h>

#define NLINES 10
#define NCOLS 40

void init_wins(WINDOW **wins, int n);
void win_show(WINDOW *win, char *label, int label_color);
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);

int main()
{	WINDOW *my_wins[3];
	PANEL  *my_panels[3];
	PANEL  *top, *p, *pe;
	int ch, res;
	mmask_t mmask;
	MEVENT mevent;
	char buf[255];

	/* Initialize curses */
	initscr();
	start_color();
	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	mmask = mousemask(REPORT_MOUSE_POSITION|BUTTON1_CLICKED, NULL);

	/* Initialize all the colors */
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_GREEN, COLOR_BLACK);
	init_pair(3, COLOR_BLUE, COLOR_BLACK);
	init_pair(4, COLOR_CYAN, COLOR_BLACK);

	init_wins(my_wins, 3);
	
	/* Attach a panel to each window */ 	/* Order is bottom up */
	my_panels[0] = new_panel(my_wins[0]); 	/* Push 0, order: stdscr-0 */
	my_panels[1] = new_panel(my_wins[1]); 	/* Push 1, order: stdscr-0-1 */
	my_panels[2] = new_panel(my_wins[2]); 	/* Push 2, order: stdscr-0-1-2 */

	/* Set up the user pointers to the next panel */
	set_panel_userptr(my_panels[0], my_panels[1]);
	set_panel_userptr(my_panels[1], my_panels[2]);
	set_panel_userptr(my_panels[2], my_panels[0]);

	/* Update the stacking order. 2nd panel will be on top */
	update_panels();

	/* Show it on the screen */
	attron(COLOR_PAIR(4));
	mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F2 to Exit)");
	sprintf(buf, "Debug infos : mmask=%lx", mmask);
	mvprintw(LINES - 3, 0, buf);
	attroff(COLOR_PAIR(4));
	doupdate();

	top = my_panels[2];
	while((ch = getch()) != KEY_F(2))
	{	switch(ch)
		{	case 9: // This is tab key, but ive not found the right symbol... other that '\t'
				top = (PANEL *)panel_userptr(top);
				top_panel(top);
				break;
			case KEY_MOUSE:
				// Seems to have a mouse event
				res = getmouse(&mevent);
				if ( res == OK ) {
					// Try to find in which panel (search first in top-level panel and go down)
					pe=NULL;
					p=top;
					do {
						if ((p == NULL) || wenclose(panel_window(p), mevent.y, mevent.x) ) {
							pe = p;
							break;
						}
						p = (PANEL *)panel_userptr(top);
					} while (p != top);

					// If we found a panel
					if (pe != NULL) {
						// "switch" depending on event kind
						if ( (mevent.bstate & BUTTON1_CLICKED) == BUTTON1_CLICKED) {
							// A panel was clicked, set that panel on top
							top = pe;
							top_panel(top);
							// FIXME : the userptr chain of panel must reflect panel order !
							// Or may be we can crawl panels by order with ncurses method
						}	
					}
/*
					if ( (mevent.bstate & BUTTON1_CLICKED) == BUTTON1_CLICKED) {
						attron(COLOR_PAIR(4));
						sprintf(buf, "BUTTON1_CLICKED at %i/%i/%i  ", mevent.x, mevent.y, mevent.z);
						mvprintw(LINES - 4, 0, buf);
						attroff(COLOR_PAIR(4));
						
					}
					*/
				}
				break;
			default:
				attron(COLOR_PAIR(4));
				sprintf(buf, "Unknown key : 0x%x  ", ch);
				mvprintw(LINES - 3, 0, buf);
				attroff(COLOR_PAIR(4));
		}
		update_panels();
		doupdate();
	}
	endwin();
	return 0;
}

/* Put all the windows */
void init_wins(WINDOW **wins, int n)
{
	int x, y, i;
	char label[80];

	y = 2;
	x = 10;
	for(i = 0; i < n; ++i)
	{	wins[i] = newwin(NLINES, NCOLS, y, x);
		sprintf(label, "Window Number %d", i + 1);
		win_show(wins[i], label, i + 1);
		y += 3;
		x += 7;
	}
}

/* Show the window with a border and a label */
void win_show(WINDOW *win, char *label, int label_color)
{	int startx, starty, height, width;

	getbegyx(win, starty, startx);
	getmaxyx(win, height, width);

	box(win, 0, 0);
	mvwaddch(win, 2, 0, ACS_LTEE); 
	mvwhline(win, 2, 1, ACS_HLINE, width - 2); 
	mvwaddch(win, 2, width - 1, ACS_RTEE); 
	
	print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
{	int length, x, y;
	float temp;

	if(win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if(startx != 0)
		x = startx;
	if(starty != 0)
		y = starty;
	if(width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length)/ 2;
	x = startx + (int)temp;
	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win, color);
	refresh();
}