//-*-c++-*-
// -------------------------------------------
// RCS data:
// $Date: 2003/06/23 14:47:23 $
// $Revision: 1.1.1.1 $
// $Source: /cvsroot/miwm/miwm/miwm/mouse.cc,v $
// $Id: mouse.cc,v 1.1.1.1 2003/06/23 14:47:23 bwise837 Exp $
// $RCSfile: mouse.cc,v $
// -------------------------------------------
// Copyright by Ben Paul Wise.
// -------------------------------------------
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
// -------------------------------------------

#include	<stdio.h>
#include	<stdlib.h>

#include	<X11/X.h>
#include	<X11/Xos.h>
#include	<X11/Xlib.h>
#include	<X11/Xutil.h>

#include	"miwm.h"
#include	"ws.h"

// -------------------------------------------

int current_item = -1;	/* Last known selected menu item. -1 if none. */
menuitem * currentMenu = NULL;

// -------------------------------------------

void
getMouse(int * x, int * y) {
  Window dw1, dw2;
  int t1, t2;
  unsigned int b;

  XQueryPointer(dpy, root, &dw1, &dw2, x, y, &t1, &t2, &b);
}


const char *
choose_label(Client * c) {
  return (c->name != 0) ? c->name :
    ((c->fallback_name != 0) ? c->fallback_name : "<unknown>");
}


// void
// updateMenu(Client *) {
//   return;
// }

// -------------------------------------------
// Client*
// clientFromMenuItem(int n) {
//   Client *c = NULL;
//   return c;
// }

// -------------------------------------------

void hide(Client *c) {
  currentMenu = NULL;

  if (c == 0)
    return;

  theWM->hiddenClients->prepend((void*)c); // LIFO order, like a stack

//   if (c == theWM->workSpace->topClient)
//     theWM->workSpace->topClient = NULL;

  if (current == c) 
    current = NULL;

  theWM->hideClient(c);
  return;
}

// -------------------------------------------


void
unhide(int n , int map) {
  int i = 0;
  assert (theWM != NULL);
  NodeList *hcs = theWM->hiddenClients;
  Node* cND = NULL;
  Node* cND2 = NULL;
  Client *c = NULL;
  if ( (n >= 0) && (n < hcs->length())) {
    for (cND = hcs->first; ((cND != NULL) && (c == NULL)); cND = hcs->nextNode(cND)) {
      if (i == n) {
	c = ((Client*) cND->data);
	theWM->unhideClient(c);
//  	cout << "  there are " << theWM->hiddenClients->length() << " hidden " << endl;
//  	cout << "cND = " << cND << endl;
 	cND2 = theWM->hiddenClients->remove(cND);
//  	cout << "cND2 = " << cND2 << endl;
//  	cout << "  there remain " << theWM->hiddenClients->length() << " hidden " << endl;
      }
      i = i + 1;
    }
  }

  return;
}

void unhidec(Client *c, int map) {
  Node* cND;

  if (c == 0)
    return;

  cND = theWM->hiddenClients->inList((void*) c);

  if (cND != NULL) {
    theWM->hiddenClients->remove(cND);
    if (map) {
//       c = ((Client*) cND->data);
      theWM->unhideClient(c);
    }
  }

  return;
}

// -------------------------------------------
// this is the fundamental pair that actually hides/unhides
// windows, separate from menu-manipulations
// -------------------------------------------

void
WindowManager::hideClient(Client* c) { 
  XUnmapWindow(dpy, c->parent);
  XUnmapWindow(dpy, c->window);
  c->hidden = True;
  c->isMapped = 0;
  //  If the window was the current window, it so no more... 
  setactive(c, 0, 0L);
  setClientState(c, IconicState);
  return;
}

void
WindowManager::unhideClient(Client *c) {
   c->hidden = False;
   XMapRaised(dpy, c->parent);
   XMapWindow(dpy, c->window);
   c->isMapped = 1;
   setClientState(c, NormalState);
  return;
}


int
WindowManager::mouseInDeadlyBox(Client *c) {
  int rslt = 0;
  int quarter, xWindow, yWindow;
  int th = titleHeightc(c);
  // in root coords
  getMouse(&xWindow, &yWindow);   

  // convert to window coords
  xWindow = xWindow - c->size.x;
  yWindow = yWindow - c->size.y + th;
//   cout << "Testing if mouse coords (" << xWindow << " , " << yWindow << " )";
//   cout << " are in the box of client " << c->clientID << endl;
  if (th > 0) {
    quarter = (border + th) / 4;
//     cout << "Box is [ " << border << " , " << (border + 2 * quarter) << "] x ";
//     cout << "[ " << quarter << " , " << 3*quarter << " ]" << endl;
    if (xWindow > border && xWindow < (border + 2 * quarter) &&
	yWindow > quarter && yWindow < 3 * quarter)
      rslt = 1;
  }
//   cout  << "rslt is " << rslt << endl << flush;

  return rslt;
}

// -------------------------------------------
// end of mouse.cc
// -------------------------------------------
