//////////////////////////////////////////////
// NovaWM - Nova Window Manager for X11     //
//////////////////////////////////////////////
// By: Tim Walters                          //
//////////////////////////////////////////////
// Copyright (C) 2001-2002 Tim Walters      //
//////////////////////////////////////////////

////////////////////////////////////////////////////////////////
//This code is released under the terms of the GNU GPL. Refer //
//to the license file included with this source code.         //
////////////////////////////////////////////////////////////////


#include "novawm.h"

#include <string.h>

NovaWM_Menu::NovaWM_Menu ()
{
  itemHeight = 15;
  open = false;
  font = novawmFont;
}

NovaWM_Menu::~NovaWM_Menu ()
{
}

int
NovaWM_Menu::Create (int c_x, int c_y)
{
  Window window;

  XSetWindowAttributes set_attrib;

  XCharStruct charstruct;

  width = 0;
  height = (nItems * itemHeight + 4);
  int dummy;
  int i = 0;

  sel = -1;
  open = true;

  if (!font)
    font = novawmFont;
  if (!itemHeight)
    itemHeight = 15;

  //Determine the menu width
  for (i = 0; i < nItems; i++)
    {
      XTextExtents (novawmFont, itemText[i].c_str (), itemText[i].size (),
		    &dummy, &dummy, &dummy, &charstruct);

      if (charstruct.width > width)
	width = charstruct.width + 16;
    }

  set_attrib.event_mask =
    ExposureMask | ButtonPressMask | ButtonReleaseMask |
    FocusChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask;

  set_attrib.background_pixel = mainPixel;

  set_attrib.override_redirect = true;

  x = c_x;
  y = c_y;

  if (x + width > XDisplayWidth (display, screen))
    x = x - width;
  if (y + height > XDisplayHeight (display, screen))
    y = y - height;
  if (y < 0)
    y = 0;

  window = XCreateWindow (display, root, x, y, width,
			  height, 0, DefaultDepth (display,
						   screen),
			  CopyFromParent, DefaultVisual (display,
							 screen),
			  CWBackPixel | CWEventMask, &set_attrib);

  x11_window = window;

  XMapWindow (display, x11_window);

  DrawItems ();

  return 0;
}

void
NovaWM_Menu::AddItem (char *text)
{
  if (!nItems)
    nItems = 0;

  itemText.push_back (text);
  nItems++;
}

Window NovaWM_Menu::menuWindow ()
{
  return x11_window;
}

int
NovaWM_Menu::GetSelection ()
{
  return sel;
}

void
NovaWM_Menu::HighlightItem (int cusor_x, int cursor_y)
{
  int itemSel = (cursor_y - 4) / itemHeight;

  if (itemSel == sel)
    return;

  if (itemSel > nItems - 1 || itemSel < 0)
    return;

  sel = itemSel;

  XSetForeground (display, novawm_gc, BlackPixel (display, screen));

  XClearWindow (display, x11_window);

  if (strncmp (itemText[sel].c_str (), "?+MENU_SPLIT+?", 14) != 0)
    XFillRectangle (display, x11_window, novawm_gc, 0,
		    sel * itemHeight, width, itemHeight + 3);

  DrawItems ();

}

void
NovaWM_Menu::DrawItems ()
{
  //First draw the border
  XSetForeground (display, novawm_gc, BlackPixel (display, screen));
  XDrawLine (display, x11_window, novawm_gc, width - 1, 1, width - 1, height);
  XDrawLine (display, x11_window, novawm_gc, 1, height - 1, width,
	     height - 1);

  XSetForeground (display, novawm_gc, WhitePixel (display, screen));
  XDrawLine (display, x11_window, novawm_gc, 0, 0, 0, height - 1);
  XDrawLine (display, x11_window, novawm_gc, 0, 0, width - 1, 0);

  if (font != novawmFont)
    XSetFont (display, novawm_gc, font->fid);

  //Draw the Items
  for (int i = 0; i < nItems; i++)
    {
      if (strncmp (itemText[i].c_str (), "?+MENU_SPLIT+?", 14) == 0)
	{
	  XSetForeground (display, novawm_gc, BlackPixel (display, screen));

	  XDrawLine (display, x11_window, novawm_gc, 2,
		     i * itemHeight + 9, width - 2, i * itemHeight + 9);

	  XSetForeground (display, novawm_gc, WhitePixel (display, screen));


	  XDrawLine (display, x11_window, novawm_gc, 2,
		     i * itemHeight + 11, width - 2, i * itemHeight + 11);

	}

      else
	{
	  XDrawString (display, x11_window, novawm_gc, 3,
		       i * itemHeight + itemHeight, itemText[i].c_str (),
		       itemText[i].size ());
	}
    }

  if (font != novawmFont)
    XSetFont (display, novawm_gc, novawmFont->fid);

}

void
NovaWM_Menu::SetFont (XFontStruct * xfont)
{
  font = xfont;
}

void
NovaWM_Menu::SetItemHeight (int height)
{
  itemHeight = height;
}

void
NovaWM_Menu::Clear ()
{
  nItems = 0;
  itemText.clear ();

  /*for (int i = 0; i < nItems - 1; i++)
     {
     itemText[i] = "\0";
     } */
}

bool NovaWM_Menu::isOpen ()
{
  return open;
}

void
NovaWM_Menu::Destroy ()
{
  if (open == true)
    {
      open = false;
      XDestroyWindow (display, x11_window);
      winmgr.AddUnmapIgnore (x11_window);	//unmapignore++;
    }
}


syntax highlighted by Code2HTML, v. 0.9.1