/*********************************************************************
 *
 *         EZWGL, the EZ Widget and Graphics Library
 *
 *             Copyright (C) 1996, 1997  Maorong Zou
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **********************************************************************/
/*
 *  June 1996.  Beta Release.
 *  Sept 1996.  Release Version 1.0
 *  Dec 1996.  Release Version 1.1 Beta
 *  April 1997.  Release Version 1.2
 *  November 1997.  Release Version 1.3
 */
/*****************************************************************
 ***                                                           ***
 ***       Internal Toplevel Widget                            ***
 ***                                                           ***
 *****************************************************************/
#define _EZ_WIDGET_ITOPLEVEL_C_
#include "EZ_Widget.h"

/*********************************************************************
 * 
 *  Functions implemented in this file:
 */
EZ_Widget       *EZ_CreateFreeLabel MY_ANSIARGS((EZ_Widget *widget, char *label));
EZ_Widget       *EZ_CreateIcon MY_ANSIARGS((void));
EZ_Widget       *EZ_CreateIToplevelFrame MY_ANSIARGS((EZ_Widget *widget, char *label));
void            EZ_IToplevelEventHandle MY_ANSIARGS((EZ_Widget *widget, XEvent *event));

/*********************************************************************
 * 
 *  Local Variables.
 */
static EZ_WidgetHandle EZ_IToplevelHandle =
{ 
  EZ_ComputeWidgetLabelSize,   /* same as label */
  EZ_DrawWidgetLabel,
  EZ_FreeWidgetLabelData,
  EZ_IToplevelEventHandle,     /* response button events */
};

/*********************************************************************/

EZ_Widget  *EZ_CreateIcon()
{
  EZ_Widget *tmp = EZ_CreateIToplevelFrame(NULL, NULL);
  if(tmp)
    {
      EZ_WidgetBorderStyle(tmp) = EZ_BORDER_UP;
      EZ_WidgetBorderWidth(tmp) = 2;
    }
  return(tmp);
}

EZ_Widget  *EZ_CreateFreeLabel(parent, label)
     EZ_Widget *parent; char *label;
{
  return(EZ_CreateIToplevelFrame(parent, label));
}

EZ_Widget  *EZ_CreateIToplevelFrame(parent, label)
     EZ_Widget *parent; char *label;
{
  EZ_Widget  *tmp;
  
  tmp = EZ_CreateLabel(parent, label);

  EZ_WidgetHandlingFunctions[EZ_WIDGET_ITOPLEVEL] = &EZ_IToplevelHandle;

  EZ_WidgetType(tmp) = EZ_WIDGET_ITOPLEVEL;
  EZ_SetWidgetXSetFlag(tmp);
  EZ_SetWidgetYSetFlag(tmp);
  EZ_WidgetBorderStyle(tmp)  = EZ_BORDER_FRAMED_UP;
  EZ_WidgetBorderWidth(tmp)  = 0;
  EZ_WidgetSepX(tmp)         = 4;
  EZ_WidgetSepY(tmp)         = 3;
  EZ_WidgetPadB(tmp)         = 0;
  EZ_SetDoNotPropagateFlag(tmp);
  EZ_SetWidgetFocusableFlag(tmp);  

  return(tmp);
}

/****************************************************************************/
void  EZ_IToplevelEventHandle(widget, event)
     EZ_Widget *widget;
     XEvent    *event;
{
  int     x,y, bx,by, dx,dy, rootx, rooty, oldx, oldy, done, buttonP;
  XEvent  xevent;
  Window  root, child;
  unsigned int    mask;
    
  if(widget == (EZ_Widget *)NULL || 
     widget == EZ_BubbleHelp) return;

  switch(event->type)
    {
    case Expose:
      EZ_DrawWidget(widget);
      break;
    case ButtonPress:
      if(EZ_WidgetParent(widget) != NULL)
	{
	  XRaiseWindow(EZ_Display, EZ_WidgetWindow(widget));
	  EZ_DrawWidget(widget);      
	}
      buttonP = event->xbutton.button;
      if(buttonP == Button1)
	{
	  Time  time_stamp = event->xbutton.time;   
	  int   elapsedtime = EZ_LastButton1ClickTime - time_stamp;

	  EZ_LastButton1ClickTime = time_stamp;
	  
	  if(ABSV(elapsedtime) < DOUBLE_CLICK_TIME_INTERVAL)
	    {
	      if(EZ_WidgetCallBackFunc(widget))
		{
		  { EZ_ExecuteWidgetCallBacks(widget);}
		  return;
		}
	    }
	}
      if(EZ_LabelMovable(widget) != 0) /* move the label */
	{
	  bx = event->xbutton.x;
	  by = event->xbutton.y;
	  XQueryPointer(EZ_Display, RootWindow(EZ_Display, EZ_ScreenNum),
			&root,                          /* root return win */
			&child,                         /* child ret win   */
			&oldx, &oldy,                   /* x, y in root    */
			&x,&y,                          /* x, y in win     */
			&mask);  
	  /*
	   * wait for a matching ButtonRelease. In the mean time, process
	   * MotionNotify and SelectionRequest events.
	   */
	  done = 0;
	  while(!done)
	    {
	      XNextEvent(EZ_Display, &xevent); 
	      EZ_FilterEvent(&xevent);
	      if(xevent.xany.window != EZ_WidgetWindow(widget))
		EZ_WidgetDispatchEvent(&xevent);
	      else
		{
		  switch(xevent.type)
		    {
		    case MotionNotify:
		      XQueryPointer(EZ_Display, RootWindow(EZ_Display, EZ_ScreenNum),
				    &root,       /* root return win */
				    &child,      /* child ret win   */
				    &rootx, &rooty,   /* x, y in root    */
				    &x,&y,            /* x, y in win     */
				    &mask);  
		      dx = rootx - oldx;  dy = rooty - oldy;
		      oldx = rootx;   oldy = rooty;
	  
		      EZ_WidgetOriginX(widget) += dx;
		      EZ_WidgetOriginY(widget) += dy;
		      EZ_ClearWidgetSizeComputedFlag(widget);
		      if(EZ_LabelMotionCallBack(widget))
			{
			  EZ_CallBackStruct *callbacks = EZ_LabelMotionCallBack(widget);
			  EZ_HandleMotionCallBacks(widget,callbacks);
			}
		      EZ_ReDisplayWidget(widget);
		      while(XCheckTypedEvent(EZ_Display, MotionNotify, &xevent))
			EZ_FilterEvent(&xevent);
		      break;
		    case ButtonRelease:
		      if(xevent.xbutton.button == buttonP)   done = 1;
		      break;
		    default:
		      break;
		    }
		}
	    }
	  /* done, if this is a toplevel, generate embeding request */
	  if(EZ_WidgetParent(widget) == (EZ_Widget *)NULL &&
	     EZ_GetWidgetEmbededFlag(widget) == 0)
	    EZ_GenerateEmbedingRequest(widget, oldx - bx,oldy -by, 
				       (int)EZ_WidgetWidth(widget),
				       (int)EZ_WidgetHeight(widget));
	}
      break;
    case EnterNotify:
      if(EZ_WidgetParent(widget) == NULL && EZ_WidgetMapped(widget)  &&
	 EZ_LabelDontTakeFocus(widget) == 0 )
	{
	  if(event->xcrossing.focus == False)  EZ_ResetFocus(widget, 100);
	}
      break;
    case LeaveNotify:
      break;
    default:
      break;
    }
}

/*****************************************************************************/
#undef _EZ_WIDGET_ITOPLEVEL_C_


