//
// Copyright (C) 1999-2002 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

#include <Carbon/Carbon.h>
#include <mac/WSDmacScrFrameDev.h>
#include <mac/WSDmacAppDev.h>
#include <mac/WSDmacDraw.h>
#include <mac/WSmcom.h>
#include <WSCdevice.h>
#include <WSCcolorSet.h>
#include <WSCbase.h>


WSMFclassInit(WSDmacScrFrameDev,WSDmacFormDev);
WSDdev* _wsdmacScrdev_init_(){
  return new WSDmacScrFrameDev();
}

class _WSDmacScrFrameDev_init_ {
  public:_WSDmacScrFrameDev_init_(){
     WSGIappDevice()->setCreateHandler("scrFrameDev",_wsdmacScrdev_init_);
  };
};
static _WSDmacScrFrameDev_init_ _init_to_run_WSDmacScrFrameDev_;

WSDmacScrFrameDev::WSDmacScrFrameDev(){
  _scr_form = 0;
  _work_width =0;
  _work_height =0;
  _title_height = 0;
}

WSDmacScrFrameDev::~WSDmacScrFrameDev(){
  destroyWindow();
}

long WSDmacScrFrameDev::setValue(long kind,void* data){
  char psbk = getPixmapStyle();
  setPixmapStyle( WS_DIRECT_WINDOW);
  WSDmacFormDev::setValue(kind,data);
  setPixmapStyle(psbk);
printf("WSDmacScrFrameDev::setValue \n");
printf("not supported.. %s %d\n",__FILE__,__LINE__);
#if 0 //XXZZ

  Arg args[5];
  long vl;
  WSDcolor* color;
  char fl;
  switch(kind){
    case WSDEV_X: 
	         if (_scr_form != NULL){
               if (getVisible() == True){
                 WSDxformDev* pdev = getParentAreaDev();
                 if (pdev != NULL && (pdev->getWidth() < *(short*)data + _w_w ||
                                       pdev->getHeight() < _w_y +_w_h )){
                   XtUnmanageChild((Widget)_scr_form);
                 }
               }
  
               XtSetArg(args[0],XtNx,*(short*)data);
               XtSetValues((Widget)_scr_form,args,1);
               if (getVisible() == True){
                 XtManageChild((Widget)_scr_form);
               }
             }
             break;
    case WSDEV_Y:
	         if (_scr_form != NULL){
               if (getVisible() == True){
                 WSDxformDev* pdev = getParentAreaDev();
                 if (pdev != NULL &&(pdev->getHeight() < *(short*)data + _w_h ||
                                       pdev->getWidth()  < _w_x + _w_w)){
                   XtUnmanageChild((Widget)_scr_form);
                 }
               }
               XtSetArg(args[0],XtNy,*(short*)data);
               XtSetValues((Widget)_scr_form,args,1);
               if (getVisible() == True){
                 XtManageChild((Widget)_scr_form);
               }
             }
             break;
    case WSDEV_WIDTH:
	         if (_scr_form != NULL && *(WSCushort*)data > 0){
               XtSetArg(args[0],XtNwidth,*(WSCushort*)data);
               XtSetValues((Widget)_scr_form,args,1);
			 }
             break;
    case WSDEV_HEIGHT:
	         if (_scr_form != NULL && *(WSCushort*)data > 0){
               XtSetArg(args[0],XtNheight,*(WSCushort*)data);
               XtSetValues((Widget)_scr_form,args,1);
			 }
             break;
    case WSDEV_BACKCOLOR:
	         if (_widget != NULL){
               _bg = *(short*)data;
               color = WSGIappColorSet()->getColor(*(short*)data);
               if (color != NULL){
                 XtSetArg(args[0],XtNbackground,color->getValue1());
                 XtSetValues((Widget)_widget,args,1);
                 XtSetValues((Widget)_scr_form,args,1);
               }
             }
             break;
    case WSDEV_WORK_X:
             vl = *(WSCushort*)data;
             if (vl > _work_width - _w_w){
               vl = _work_width - _w_w;
               if (vl < 0){
                 vl = 0;
               }
             }
             _h_scr_pos = vl;
             if (_addr_change_handler != NULL){
               _addr_change_handler(this,_handler_data);
             }

             if (_widget != NULL){
               XtSetArg(args[0],XtNx,-_h_scr_pos);
               XtSetValues(_widget,args,1);
             }
             break;
    case WSDEV_WORK_Y:
             vl = *(WSCushort*)data;
             if (vl > _work_height - _w_h){
               vl = _work_height - _w_h;
               if (vl < 0){
                 vl = 0;
               }
             }
             _v_scr_pos = vl;
             if (_addr_change_handler != NULL){
               _addr_change_handler(this,_handler_data);
             }
             if (_widget != NULL){
               XtSetArg(args[0],XtNy,-_v_scr_pos);
               XtSetValues(_widget,args,1);
             }
             break;
    case WSDEV_WORK_WIDTH:
             if (getPixmapStyle() != WS_DIRECT_WINDOW){
               if (_work_width < *(WSCushort*)data){ //scrform expose
                                                     //redraw bugfix
                 destroyPixmap();
               }
             }
             _work_width = *(WSCushort*)data;

             if (_widget != NULL){
               XtSetArg(args[0],XtNwidth,*(WSCushort*)data);
               XtSetValues((Widget)_widget,args,1);
             }
             if (_h_scr_pos > _work_width - _w_w){
               _h_scr_pos = _work_width - _w_w;
               if (_h_scr_pos < 0){
                 _h_scr_pos = 0;
               }
               if (_addr_change_handler != NULL){
                 _addr_change_handler(this,_handler_data);
               }
             }
             break;

    case WSDEV_WORK_HEIGHT:
             if (getPixmapStyle() != WS_DIRECT_WINDOW){
               if (_work_height < *(WSCushort*)data){//scrform expose
                                                     //redraw bugfix
                 destroyPixmap();
               }
             }
             _work_height = *(WSCushort*)data;

             if (_widget != NULL){
               XtSetArg(args[0],XtNheight,*(WSCushort*)data);
               XtSetValues((Widget)_widget,args,1);
             }
             if (_v_scr_pos > _work_height - _w_h){
               _v_scr_pos = _work_height - _w_h;
               if (_v_scr_pos < 0){
                 _v_scr_pos = 0;
               }
               if (_addr_change_handler != NULL){
                 _addr_change_handler(this,_handler_data);
               }
             }
             break;
    case WSDEV_PIXMAP_STYLE:
             fl = *(char*)data;
             setPixmapStyle(fl);
             destroyPixmap();
             break;
    case WSDEV_VHEAD_X:
             _p1_x = *(WSCushort*)data;
             break;
    case WSDEV_VHEAD_Y:
             _p1_y = *(WSCushort*)data;
             break;
    case WSDEV_VFOOT_X:
             _p2_x = *(WSCushort*)data;
             break;
    case WSDEV_VFOOT_Y:
             _p2_y = *(WSCushort*)data;
             break;
    case WSDEV_TITLE_HEIGHT:
             _title_height = *(WSCushort*)data;
             break;
    case WSDEV_GRAB_POINTER:
             if (_widget == NULL){
               break;
             }
             fl = *(WSCbool*)data;
             if (fl != False){
               XGrabPointer(XtDisplay(_widget),XtWindow(_widget),False,
                  ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
                  GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
               XGrabKeyboard(XtDisplay(_widget),XtWindow(_widget),False,
                  GrabModeAsync,GrabModeAsync,CurrentTime);
             }else{
               XUngrabPointer(XtDisplay(_widget),CurrentTime);
               XUngrabKeyboard(XtDisplay(_widget),CurrentTime);
             }
             break;

    default:
      return WS_ERR;
  }
//  setPixmapStyle(psbk);
  return WS_NO_ERR;
#endif //XXZZ
printf("WSDmacScrFrameDev::setValue \n");
printf("not supported.. %s %d\n",__FILE__,__LINE__);
  return WS_NO_ERR;
}

long WSDmacScrFrameDev::createPixmap(){
printf("WSDmacScrFrameDev::createPixmap \n");
printf("not supported.. %s %d\n",__FILE__,__LINE__);
#if 0 //XXZZ
  if (getGC() == 0){
    return WS_ERR;
  }

  WSCushort w,h;    
  w = _work_width;
  if (_work_width <1){
    w = 1;
  }
  h = _work_height;
  if (_work_height <1){
    h = 1;
  }
  Pixmap pix = WSGFxGetPixmap(w,h);
  setPixmap(pix);
  _setup_pixmap(0,0,w,h,_bg_no,_bp_no);
  exposeExecute(0,0,w,h);
  return WS_NO_ERR;
#endif //XXZZ
  return WS_ERR;
}
long WSDmacScrFrameDev::createWindow(){
  return WSDmacFormDev::createWindow();

//printf("WSDmacScrFrameDev::createWindow not supported.. %s %d\n\n",__FILE__,__LINE__);
//  return WS_ERR;
#if 0 //XXZZ
  if (_scr_form != 0){
    WSDxformDev* xdev = getParentAreaDev();
    if (xdev != NULL && xdev->getWidget() != _pwidget){
      XtRemoveCallback(_widget,XtNdestroyCallback,_evh_delete2,this);
    }else{
      return WS_NO_ERR;
    }
  }
  short x,y;    
  WSCushort w,h;    
  getWindowSize(&x,&y,&w,&h);
  if (w == 0){
    w = 1;
  }
  if (h == 0){
    h = 1;
  }
  _h_scr_pos = 0;
  _v_scr_pos = 0;

  WSDdev*      pdev = getParentDev();
  if (pdev == NULL){
    assert(0);
    return WS_ERR;
  }
  WSDxformDev* xdev = (WSDxformDev*)pdev->cast("WSDxformDev");
  if (xdev == NULL){
    return WS_ERR;
  }

  Arg args[12];
  long anum =0;
  if (_bg != -1){
    WSDcolor* color = WSGIappColorSet()->getColor(_bg);
    if (color != NULL){
       XtSetArg(args[anum],XtNbackground,color->getValue1()); anum++;
    }
  }

  XtSetArg(args[anum],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP); anum++;
  XtSetArg(args[anum],XtNx,x); anum++;
  XtSetArg(args[anum],XtNy,y); anum++;
  XtSetArg(args[anum],XtNwidth,w); anum++;
  XtSetArg(args[anum],XtNheight,h); anum++;
  XtSetArg(args[anum],XtNborderWidth,0); anum++;

  _pwidget = xdev->getWidget();
  _scr_form = XtCreateWidget("macScrarea",formWidgetClass,_pwidget,args,6);

  anum =0;
  if (_bg != -1){
    WSDcolor* color = WSGIappColorSet()->getColor(_bg);
    if (color != NULL){
       XtSetArg(args[anum],XtNbackground,color->getValue1()); anum++;
    }
  }
  XtSetArg(args[anum],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP); anum++;
  XtSetArg(args[anum],XtNx,0); anum++;
  XtSetArg(args[anum],XtNy,0); anum++;
  XtSetArg(args[anum],XtNwidth,1000); anum++;
  XtSetArg(args[anum],XtNheight,1000); anum++;
  XtSetArg(args[anum],XtNborderWidth,0);anum++;

  _widget = XtCreateWidget("wsdxwa",formWidgetClass, _scr_form,args,anum);
  XtManageChild(_widget);

  XtAddEventHandler(_widget,ExposureMask,False,(XtEventHandler)_evh_expose,(WSDxformDev*)this);
  XtAddEventHandler(_widget,ButtonPressMask,False,(XtEventHandler)_evh_btn_press,(WSDxformDev*)this);
  XtAddEventHandler(_widget,ButtonReleaseMask,False,(XtEventHandler)_evh_btn_release,(WSDxformDev*)this);
  XtAddEventHandler(_widget,ButtonMotionMask | PointerMotionMask,False,(XtEventHandler)_evh_mouse_move,(WSDxformDev*)this);
  XtAddEventHandler(_scr_form,StructureNotifyMask,False,(XtEventHandler)_evh_resize,this);
  XtAddEventHandler(_widget,EnterWindowMask,False,(XtEventHandler)_evh_mouse_in,(WSDxformDev*)this);
  XtAddEventHandler(_widget,LeaveWindowMask,False,(XtEventHandler)_evh_mouse_out,(WSDxformDev*)this);
  XtAddEventHandler(_widget,KeyPressMask | KeyReleaseMask,False,(XtEventHandler)_evh_dummy,(WSDxformDev*)this);
  XtAddCallback(_widget,XtNdestroyCallback,_evh_delete2,this);
  return WS_NO_ERR;
#endif //XXZZ
}

long WSDmacScrFrameDev::destroyWindow(){
#if 0 //XXZZ
  if (_widget != 0){
    XtRemoveEventHandler(_widget,ExposureMask,False,(XtEventHandler)_evh_expose,(WSDxformDev*)this);
    XtRemoveEventHandler(_widget,ButtonPressMask,False,(XtEventHandler)_evh_btn_press,(WSDxformDev*)this);
    XtRemoveEventHandler(_widget,ButtonReleaseMask,False,(XtEventHandler)_evh_btn_release,(WSDxformDev*)this);
    XtRemoveEventHandler(_widget,ButtonMotionMask | PointerMotionMask,False,(XtEventHandler)_evh_mouse_move,(WSDxformDev*)this);
    XtRemoveEventHandler(_widget,EnterWindowMask,False,(XtEventHandler)_evh_mouse_in,(WSDxformDev*)this);
    XtRemoveEventHandler(_widget,LeaveWindowMask,False,(XtEventHandler)_evh_mouse_out,(WSDxformDev*)this);
    XtRemoveEventHandler(_widget,KeyPressMask | KeyReleaseMask,False,(XtEventHandler)_evh_dummy,(WSDxformDev*)this);
    XtRemoveCallback(_widget,XtNdestroyCallback,_evh_delete2,this);
    XtDestroyWidget(_widget);
  }
  if (_scr_form != 0){
    XtRemoveEventHandler(_scr_form,StructureNotifyMask,False,(XtEventHandler)_evh_resize,this);
    XtDestroyWidget(_scr_form);
  }
  _pwidget = 0;
  _widget = 0;
  _scr_form = 0;
//  setDependDev(NULL);
  setInitialized(False);
//  destroyAllDependChildren();
  return WS_NO_ERR;
#endif //XXZZ
printf("WSDmacScrFrameDev::destroyWindow not supported.. %s %d\n\n",__FILE__,__LINE__);
  return WS_ERR;
}

long WSDmacScrFrameDev::setVisible(WSCbool fl){
  return WSDmacFormDev::setVisible(fl);
#if 0 //XXZZ
  WSCbool bk = getVisible();
  WSDdev::setVisible(fl);
  if (fl == False){
    WSDxformDev* xdev = getParentAreaDev();
    if (xdev != NULL && xdev->getWidget() == 0){
      destroyWindow();
    }else{
      if (_scr_form != 0){
        XtUnmanageChild(_scr_form);
      }
    }
  }else{

    if (_scr_form == 0){
      if ( createWindow() == WS_ERR){
	      return WS_ERR;
       }
    }

    if (getPixmapStyle() != WS_DIRECT_WINDOW){
      if (bk == False){
        //delete the pixmap to create int the expose handler
        destroyPixmap(); 
      }
    }
    Arg args[12];
    long anum =0;
    XtSetArg(args[anum],XtNborderWidth,0);anum++;
    XtSetValues((Widget)_scr_form,args,anum);
    XtSetValues((Widget)_widget,args,anum);
    XtManageChild(_scr_form);
  }
  return WS_NO_ERR;
#endif //XXZZ
printf("WSDmacScrFrameDev::setVisible not supported.. %s %d\n\n",__FILE__,__LINE__);
  return WS_ERR;
}
#if 0 //XXZZ
void WSDmacScrFrameDev::_evh_delete2(Widget w,XtPointer ptr,XtPointer ){
   WSDmacScrFrameDev* dev = (WSDmacScrFrameDev*)ptr;

   if (dev->_widget != w){
     return;
   }
   dev->_pwidget = 0;
   dev->_scr_form = 0;
   dev->_widget = 0;
   dev->setInitialized(False);
}
void WSDmacScrFrameDev::_evh_resize(Widget,XtPointer ptr,XEvent* ev,WSCbool*){
  WSGIxwinAppDev()->setXEvent(ev);
  WSDmacScrFrameDev* dev = (WSDmacScrFrameDev*)ptr;
  if (ev->type == ConfigureNotify){
    Position x;
    Position y;
    Dimension width;
    Dimension height;
    Arg args[4];
    XtSetArg(args[0],XtNx,&x);
    XtSetArg(args[1],XtNy,&y);
    XtSetArg(args[2],XtNwidth,&width);
    XtSetArg(args[3],XtNheight,&height);
    XtGetValues(dev->_scr_form,args,4);

    WSCrect area;
    area.setRect(x,y,width,height);
    dev->onResize(&area);
    WSGIxwinAppDev()->setXEvent(NULL);
  }
}
#endif //XXZZ

void WSDmacScrFrameDev::getDispAddr(short* ox,short* oy){

  short gx,gy;
  WSDwindowDev::getDispAddr(&gx,&gy);

  gx -=_h_scr_pos;
  gy -=_v_scr_pos;

  *ox = gx;
  *oy = gy;
}

long WSDmacScrFrameDev::beginDraw(short x,short y,WSCushort w,WSCushort h,
                         WSCbool absolute,WSCbool scaling){
if (getVisible() == False){
  return WS_ERR;
}

if (getAttachedClient() != NULL){
printf("WSDmacFormDev::beginDraw D2 inst=%s\n",getAttachedClient()->getInstanceName());
}
  long ret = WSDwindowDev::beginDraw(x,y,w,h,absolute,scaling);
  if (ret != WS_NO_ERR){
    return ret;
  }

  long wx = _w_x;
  long wy = _w_y;
  if (_is_win != False){
    wx = 0;
    wy = 0;
  }
printf("WSDmacFormDev::beginDraw D15 %s xywh=%d,%d,%d,%d\n",getAttachedClient()->getInstanceName(),x,y,w,h);
printf("WSDmacFormDev::beginDraw D7 %s wx,wy=%d,%d\n",getAttachedClient()->getInstanceName(),wx,wy);
  long px,py;
  WSCulong pw,ph;
  long cx,cy;
  WSCulong cw,ch;
  getVaridArea(&px,&py,&pw,&ph);
//  WSGFandArea(wx,wy,_w_w,_w_h,px + wx,py + wy,pw,ph,&cx,&cy,&cw,&ch);
//XXZZXXZZ
  WSGFandArea(wx,wy,_w_w,_w_h,px,py,pw,ph,&cx,&cy,&cw,&ch);
  px = cx - wx;
  py = cy - wy;
  pw = cw;
  ph = ch;
  WSGFandArea(x,y,w,h,px,py,pw,ph,&cx,&cy,&cw,&ch);
printf("WSDmacFormDev::beginDraw D15 %s %d,%d,%d,%d varid=%d,%d,%d,%d\n",getAttachedClient()->getInstanceName(),wx,wy,_w_w,_w_h,px,py,pw,ph);
  RgnHandle rh1 = NewRgn();
  RgnHandle rh2 = NewRgn();
  RgnHandle rh3 = NewRgn();
  RgnHandle rh4 = NewRgn();
  GetClip(rh1);
  getAbsoluteGeometry(&px,&py,&pw,&ph);

  SetRectRgn(rh2,cx+px,cy+py,cx+px+cw,cy+py+ch);
  SectRgn(rh1,rh2,rh3);

  CopyRgn(rh3,rh1);

  SetRectRgn(rh4,0,0,0x7fff,0x7fff);

  long num = _child_list.getNum();
  if (num > 0){
    long i;
    long set = False;
    for(i=0; i<num; i++){
      WSDmacFormDev* child = (WSDmacFormDev*)_child_list[i];
      if (child->getVisible() == False){
        continue;
      }
      long cx,cy,cw,ch;
      child->getAbsoluteGeometry(&cx,&cy,&cw,&ch);
      SetRectRgn(rh2,cx,cy,cx+cw,cy+ch);
printf(" WSDmacFormDev::beginDraw D15 clip out child=%s %d,%d,%d,%d\n",child->getAttachedClient()->getInstanceName(),cx,cy,cw,ch);
      XorRgn(rh2,rh4,rh3);
      CopyRgn(rh3,rh2);
      SectRgn(rh1,rh2,rh3);
      CopyRgn(rh3,rh1);
//      set = True;
    }
//    if (set != False){
//      SetClip(rh1);
//    }
  }
  SetClip(rh1);
#if 0
  RGBForeColor(&_bgc);
//  Pattern whitept;
//  GetQDGlobalsWhite(&whitept);
  Rect rect;
  SetRect(&rect,wx,wy,wx+_w_w,wy+_w_h);
  PaintRect(&rect);
#endif

  DisposeRgn(rh1);
  DisposeRgn(rh2);
  DisposeRgn(rh3);
  DisposeRgn(rh4);

  return ret;
}
long WSDmacScrFrameDev::getContextResource(){
  _top_left.x = 0;
  _top_left.y = 0;
  if (_parent != NULL){
    WSCpoint* pt = (WSCpoint*)_parent->getContextResource();
    _top_left.x = pt->x;
    _top_left.y = pt->y;
  }
  _top_left.x += _w_x;
  _top_left.y += _w_y;
  _top_left.x -= _h_scr_pos;
  _top_left.y -= _v_scr_pos;
  return (long)&_top_left;
}

