//
// Copyright (C) 1999-2004 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 <WScom.h>
#include <WSCform.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSDdev.h>
#include <WSDappDev.h>
#include <WSCbaseList.h>

WSMFguiClassInitialize(WSCform,WSCbase);
WSMFversion(WSCform,WSCbase);
WSMFdefineUseDevice(WSCform,formDev);

WSCform::WSCform(WSCbase* base,char* objname):WSCbase(base,objname){
  _user_string = NULL;
  _user_value  = 0;
  _x   = 100;
  _y   = 100;
  _w   = 100;
  _h   = 30;
  _shadow_thick = 2;
//  _fore_color = WSGFcolor("black");
//  _back_color = WSGFcolor("gray85");
//  _ts_color = WSGFcolor("gray95");
//  _bs_color = WSGFcolor("gray95");
  _fore_color = WS_DF_FORECOLOR;
  _back_color = WS_DF_BACKCOLOR;
  _ts_color = WS_DF_TOPSHADOWCOLOR;
  _bs_color = WS_DF_BOTTOMSHADOWCOLOR;
  _bp_color = -1;
  _shadow_type = WS_SHADOW_OUT;
  _sensitive = True;
  _pixmap_style = WS_DYNAMIC_PIXMAP;
  _no_refresh = False;
  _mouse_no     = 0;
  _grad_no     = 0;
  _grad_margin   = 0;
  _update_resize   = 0;
  _anchor_top = 0;
  _anchor_bottom= 0;
  _anchor_left = 0;
  _anchor_right = 0;
  _anchor_top_use = False;
  _anchor_bottom_use = False;
  _anchor_left_use = False;
  _anchor_right_use = False;
  _a1_color = -1;
  _a2_color = -1;
  _a3_color = -1;
  WSGIappObjectList()->addEvent(this,WSEV_GUI_POLICY_CH);

  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCform);
    WSMFpropertyCreate(WSNname,  char*, _instance_name,WSSname );
    WSMFpropertyCreate(WSNuserString,  char*, _user_string,WSSuserString );
    WSMFpropertyCreate(WSNuserValue,   long,  _user_value,WSSuserValue  );
    WSMFpropertyCreate(WSNx,           short,   _x ,WSSx );
    WSMFpropertyCreate(WSNy,           short,   _y ,WSSy );
    WSMFpropertyCreate(WSNwidth,        WSCushort, _w ,WSSwidth );
    WSMFpropertyCreate(WSNheight,       WSCushort, _h ,WSSheight );
    WSMFpropertyCreate(WSNshadowThickness,  WSCuchar, _shadow_thick,WSSshadowThickness);
    WSMFpropertyCreate(WSNforeColor,    short,   _fore_color,WSSforeColor);
    WSMFpropertyCreate(WSNbackColor,     short,  _back_color,WSSbackColor);
    WSMFpropertyCreate(WSNtopShadowColor,short,  _ts_color,WSStopShadowColor);
    WSMFpropertyCreate(WSNbottomShadowColor,short, _bs_color,WSSbottomShadowColor );
    WSMFpropertyCreate(WSNbackPixmap, short,  _bp_color,WSSbackPixmap );
    WSMFpropertyCreate(WSNshadowType,  char,  _shadow_type,WSSshadowType );
      WSMFpropertySetSelection(WSRshadowType,WSRshadowTypeD);
    WSMFpropertyCreate(WSNvis,       WSCbool,      _vis,WSSvis );
      WSMFpropertySetSelection(WSRbool2,WSRbool2D);
    WSMFpropertyCreate(WSNdet,              WSCbool,  _sensitive,WSSdet);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNpixmapStyle,      WSCuchar,  _pixmap_style,WSSpixmapStyle);
    WSMFpropertySetSelection(WSRpixmapStyle,WSRpixmapStyleD);
    WSMFpropertyCreate( WSNmouse, WSCushort,   _mouse_no,WSSmouse  );

    WSMFpropertyCreate(WSNgradation,  WSCuchar,  _grad_no,WSSgradation);
      WSMFpropertySetSelection(WSRgradation,WSRgradationD);
    WSMFpropertyCreate(WSNgradationMargin,WSCuchar,_grad_margin,WSSgradationMargin);

    WSMFpropertyCreate(WSNanchorTop, WSCushort, _anchor_top,WSSanchorTop);
    WSMFpropertyCreate(WSNanchorBottom,WSCushort,_anchor_bottom,WSSanchorBottom);
    WSMFpropertyCreate(WSNanchorLeft,WSCushort,_anchor_left,WSSanchorLeft);
    WSMFpropertyCreate(WSNanchorRight,WSCushort,_anchor_right,WSSanchorRight);

    WSMFpropertyCreate(WSNanchorTopFlag, WSCbool, _anchor_top_use,WSSanchorTopFlag);
    WSMFpropertySetSelection(WSRbool3, WSRbool3D);
    WSMFpropertyCreate(WSNanchorBottomFlag,WSCbool,_anchor_bottom_use,WSSanchorBottomFlag);
    WSMFpropertySetSelection(WSRbool3, WSRbool3D);
    WSMFpropertyCreate(WSNanchorLeftFlag,WSCbool,_anchor_left_use,WSSanchorLeftFlag);
    WSMFpropertySetSelection(WSRbool3, WSRbool3D);
    WSMFpropertyCreate(WSNanchorRightFlag,WSCbool,_anchor_right_use,WSSanchorRightFlag);
    WSMFpropertySetSelection(WSRbool3, WSRbool3D);

    WSMFpropertyCreate(WSNexport,WSCbool,_export_,WSSexport);
    WSMFpropertySetSelection(WSRbool1, WSRbool1D);

    WSMFaddTrigger(WSEV_INITIALIZE  );
    WSMFaddTrigger(WSEV_MOUSE_MOVE  );
    WSMFaddTrigger(WSEV_MOUSE_IN    );
    WSMFaddTrigger(WSEV_MOUSE_OUT   );
    WSMFaddTrigger(WSEV_MOUSE_PRESS   );
    WSMFaddTrigger(WSEV_MOUSE_RELEASE );
    WSMFaddTrigger(WSEV_PARENT_VISIBLE_CH  );
    WSMFaddTrigger(WSEV_VISIBLE_CH  );
    WSMFaddTrigger(WSEV_EXPOSE      );
    WSMFaddTrigger(WSEV_RESIZE      );
  WSMFpropertyCreateEnd
}
WSMFproperty(WSCform,WSNname, char*, _instance_name ,WSGFstrdup("")); 
WSMFproperty(WSCform,WSNuserString, char*, _user_string ,WSGFstrdup("")); 
WSMFproperty(WSCform,WSNuserValue, long,  _user_value, 0); 
WSMFproperty(WSCform,WSNx,   short, _x, 100 );
WSMFproperty(WSCform,WSNy,   short, _y, 100 );
WSMFproperty(WSCform,WSNwidth, WSCushort, _w, 100  );
WSMFproperty(WSCform,WSNheight, WSCushort, _h, 30  );
WSMFproperty(WSCform,WSNshadowThickness, WSCuchar, _shadow_thick, 2);
//WSMFproperty(WSCform,WSNforeColor, short, _fore_color, WSGFcolor("black") );
//WSMFproperty(WSCform,WSNbackColor, short, _back_color, WSGFcolor("gray85") );
//WSMFproperty(WSCform,WSNtopShadowColor, short, _ts_color, WSGFcolor("gray95") );
//WSMFproperty(WSCform,WSNbottomShadowColor,short, _bs_color, WSGFcolor("gray55") );
WSMFproperty(WSCform,WSNforeColor, short, _fore_color, WS_DF_FORECOLOR);
WSMFproperty(WSCform,WSNbackColor, short, _back_color, WS_DF_BACKCOLOR);
WSMFproperty(WSCform,WSNtopShadowColor, short, _ts_color, WS_DF_TOPSHADOWCOLOR);
WSMFproperty(WSCform,WSNbottomShadowColor,short, _bs_color, WS_DF_BOTTOMSHADOWCOLOR);
WSMFproperty(WSCform,WSNbackPixmap, short, _bp_color, -1);
WSMFproperty(WSCform,WSNshadowType, char,    _shadow_type ,WS_SHADOW_OUT );
WSMFproperty(WSCform,WSNvis,WSCbool, _vis ,False  );
WSMFproperty(WSCform,WSNdet,WSCbool, _sensitive, True );
WSMFproperty(WSCform,WSNpixmapStyle, WSCuchar, _pixmap_style ,WS_DYNAMIC_PIXMAP);
WSMFproperty(WSCform, WSNmouse,   WSCushort,     _mouse_no     ,0);
WSMFproperty(WSCform, WSNgradation, WSCuchar, _grad_no   ,0);
WSMFproperty(WSCform, WSNgradationMargin, WSCuchar, _grad_margin ,0);
WSMFproperty( WSCform, WSNanchorTop,WSCushort,_anchor_top,0 );
WSMFproperty( WSCform, WSNanchorBottom,WSCushort,_anchor_bottom,0 );
WSMFproperty( WSCform, WSNanchorLeft,WSCushort,_anchor_left,0 );
WSMFproperty( WSCform, WSNanchorRight,WSCushort,_anchor_right,0 );
WSMFproperty( WSCform, WSNanchorTopFlag,WSCbool,_anchor_top_use,False );
WSMFproperty( WSCform, WSNanchorBottomFlag,WSCbool,_anchor_bottom_use,False );
WSMFproperty( WSCform, WSNanchorLeftFlag,WSCbool,_anchor_left_use,False );
WSMFproperty( WSCform, WSNanchorRightFlag,WSCbool,_anchor_right_use,False );
WSMFproperty( WSCform, WSNexport,WSCbool,_export_,False );

void WSCform::setWorkWSNname(char* ){}
void WSCform::getWorkWSNname(char** ){}
void WSCform::setWorkWSNuserString(char* ){}
void WSCform::getWorkWSNuserString(char** ){}
void WSCform::setWorkWSNuserValue(long ){}
void WSCform::getWorkWSNuserValue(long* ){}
void WSCform::setWorkWSNx(short data){
  if (_initialized != False && _dev != NULL){
    WSCbase* parent = getParent();
    if (parent != NULL && parent->adjustAnchor() != False){
      if (_anchor_left_use != False){
        data = _anchor_left;
        _x = _anchor_left;
      }else if (_anchor_right_use != False){
        parent->setGeometryChanged(True);
        parent->needUpdate();
        return;
      }
    }
    if (getXOffsetPtr() != 0){
      data += *getXOffsetPtr();
    }
    _dev->setValue(WSDEV_X,(void*)&data);
    _geometry_changed = True;
  }
}
void WSCform::getWorkWSNx(short* ){}
void WSCform::setWorkWSNy(short data){
  if (_initialized != False && _dev != NULL){
    WSCbase* parent = getParent();
    if (parent != NULL && parent->adjustAnchor() != False){
      if (_anchor_top_use != False){
        data = _anchor_top;
        _y = _anchor_top;
      }else if (_anchor_bottom_use != False){
        parent->setGeometryChanged(True);
        parent->needUpdate();
        return;
      }
    }
    if (getXOffsetPtr() != 0){
      data += *getYOffsetPtr();
    }
    _dev->setValue(WSDEV_Y,(void*)&data);
    _geometry_changed = True;
  }
}

void WSCform::getWorkWSNy(short* ){}
void WSCform::setWorkWSNwidth(WSCushort data){
  if (_initialized != False && _dev != NULL){
    WSCbase* parent = getParent();
    if (parent != NULL && parent->adjustAnchor() != False){
      if (_anchor_left_use != False && _anchor_right_use != False){
        parent->setGeometryChanged(True);
        parent->needUpdate();
        return;
      }
    }
    _dev->setValue(WSDEV_WIDTH,(void*)&data);
    _geometry_changed = True;
    _update_resize = True;
    if (_grad_no != 0){
      setAbsoluteDraw(True);
      needUpdate();
    }
  }else{
    _geometry_changed = True;
    _update_resize = True;
  }
}
void WSCform::getWorkWSNwidth(WSCushort* ){}
void WSCform::setWorkWSNheight(WSCushort data){
  if (_initialized != False && _dev != NULL){
//printf("WSCform::setWorkWSNheight %s %d\n",getInstanceName(),data);
    WSCbase* parent = getParent();
    if (parent != NULL && parent->adjustAnchor() != False){
      if (_anchor_top_use != False && _anchor_bottom_use != False){
        parent->setGeometryChanged(True);
        parent->needUpdate();
        return;
      }
    }
    _dev->setValue(WSDEV_HEIGHT,(void*)&data);
    _geometry_changed = True;
    _update_resize = True;
    if (_grad_no != 0){
      setAbsoluteDraw(True);
      needUpdate();
    }
  }else{
    _geometry_changed = True;
    _update_resize = True;
  }
}
void WSCform::getWorkWSNheight(WSCushort* ){}
void WSCform::setWorkWSNshadowThickness(WSCuchar ){}
void WSCform::getWorkWSNshadowThickness(WSCuchar* ){}
void WSCform::setWorkWSNforeColor(short ){}
void WSCform::getWorkWSNforeColor(short* ){}
void WSCform::setWorkWSNbackColor(short data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_BACKCOLOR,(void*)&data);
  }
  _a1_color = -1;
  _a2_color = -1;
  _a3_color = -1;
}
void WSCform::getWorkWSNbackColor(short* ){}
void WSCform::setWorkWSNtopShadowColor(short ){}
void WSCform::getWorkWSNtopShadowColor(short* ){}
void WSCform::setWorkWSNbottomShadowColor(short ){}
void WSCform::getWorkWSNbottomShadowColor(short* ){}
void WSCform::setWorkWSNbackPixmap(short data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_BACK_PIXMAP,(void*)&data);
  }
}
void WSCform::getWorkWSNbackPixmap(short* data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_BACK_PIXMAP,(void*)data);
  }
}
void WSCform::setWorkWSNshadowType(char ){}
void WSCform::getWorkWSNshadowType(char* ){}
void WSCform::setWorkWSNvis(WSCbool data){
    setVisible(data);
}
void WSCform::getWorkWSNvis(WSCbool*){}
void WSCform::setWorkWSNdet(WSCbool data){
  if (getPropertyEditMode() == False){
    if (data == False){
      _sensitive = True;
    }else{
      _sensitive = False;
    }
    setSensitive(data);
  }else{
    long val =(long)data;
    setUserData(WS_DET,(void*)val);
  }
}
void WSCform::getWorkWSNdet(WSCbool* data){
  if (getPropertyEditMode() != False){
    long tmp = (long)getUserData(WS_DET);
    WSCbool fl = (WSCbool)tmp;
    *data = fl;
  }
}
void WSCform::setWorkWSNpixmapStyle(WSCuchar data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_PIXMAP_STYLE,(void*)&data);
  }
}
void WSCform::getWorkWSNpixmapStyle(WSCuchar* ){}
void WSCform::setNoRefresh(WSCbool fl){
  _no_refresh = fl;
}

void WSCform::setWorkWSNmouse(WSCushort data ){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_MOUSE_NO,(void*)&_mouse_no);
  }
}
void WSCform::getWorkWSNmouse(WSCushort* ){}
void WSCform::setWorkWSNgradation(WSCuchar ){}
void WSCform::getWorkWSNgradation(WSCuchar* ){}
void WSCform::setWorkWSNgradationMargin(WSCuchar ){}
void WSCform::getWorkWSNgradationMargin(WSCuchar* ){}

void WSCform::setWorkWSNanchorTop(WSCushort data){
  if (_anchor_top_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorTop(WSCushort* data){}
void WSCform::setWorkWSNanchorBottom(WSCushort data){
  if (_anchor_bottom_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorBottom(WSCushort* data){}
void WSCform::setWorkWSNanchorLeft(WSCushort data){
  if (_anchor_left_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorLeft(WSCushort* data){}
void WSCform::setWorkWSNanchorRight(WSCushort data){
  if (_anchor_left_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorRight(WSCushort* data){}
void WSCform::setWorkWSNanchorTopFlag(WSCbool data){
  if (_anchor_top_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorTopFlag(WSCbool* data){}
void WSCform::setWorkWSNanchorBottomFlag(WSCbool data){
  if (_anchor_bottom_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorBottomFlag(WSCbool* data){}
void WSCform::setWorkWSNanchorLeftFlag(WSCbool data){
  if (_anchor_left_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorLeftFlag(WSCbool* data){}
void WSCform::setWorkWSNanchorRightFlag(WSCbool data){
  if (_anchor_right_use != False){
    if (getParent() != NULL){
      getParent()->setGeometryChanged(True);
      getParent()->needUpdate();
    }
  }
}
void WSCform::getWorkWSNanchorRightFlag(WSCbool* data){}

void WSCform::setWorkWSNexport(WSCbool data){
  setExported(data);
}
void WSCform::getWorkWSNexport(WSCbool* data){
}


WSCbool WSCform::getNoRefresh(){
  return _no_refresh;
}
void WSCform::setChildren(WSClistData& src){
  _children = src;
}
WSClistData& WSCform::getChildren(){
  return _children;
}
void WSCform::onVisibleChange(WSCbool fl){
  long need_resize_event = 0;
  if (fl != False && getowndev() == NULL){
    need_resize_event = 1;
  }
  WSCbase::onVisibleChange(fl);
  if (need_resize_event != 0){
    WSCrect rect;
    rect.x = _x;
    rect.y = _y;
    rect.width = _w;
    rect.height = _h;
    execEventProc(WSEV_RESIZE,(void*)&rect);
  }
}
void WSCform::onParentVisibleChange(WSCbool fl){
//printf("WSCform::onParentVisilbeChange() fl=%d\n",fl);
  long need_resize_event = 0;
  if (fl != False && getowndev() == NULL){
    need_resize_event = 1;
  }
  WSCbase::onParentVisibleChange(fl);
  if (need_resize_event != 0){
    WSCrect rect;
    rect.x = _x;
    rect.y = _y;
    rect.width = _w;
    rect.height = _h;
    execEventProc(WSEV_RESIZE,(void*)&rect);
  }
}
void WSCform::onResize(WSCrect* area){
  WSCbool fl = False;
  if (getPropertyEditMode() == False){
    _x = area->x;
    _y = area->y;
    if (_w != area->width){
      _w = area->width;
      fl = True;
    }
    if (_h != area->height){
      _h = area->height;
      fl = True;
    }
  }
  if (fl != False){
#if 0
    WSDdev* dev = getowndev();
    if (dev != NULL || _pixmap_style != WS_DIRECT_WINDOW){
      dev->setValue(WSDEV_WIDTH,&_w);
      dev->setValue(WSDEV_HEIGHT,&_h);
    }
#endif
    setAbsoluteDraw(True);
    needUpdate();
//    redraw();
  }
}
WSCform::~WSCform(){
  WSGIappObjectList()->delEvent(this,WSEV_GUI_POLICY_CH);

  WSClistData* ghlist = (WSClistData*)getUserData("GH-LIST");
  if (ghlist != NULL){
    delete ghlist;
    setUserData("GH-LIST",(void*)0);
  }
  while(1){
    if (_children.getNum() == 0){
      break;
    }
    WSCbase* child = (WSCbase*)_children[0];
    delete child;
  }
  if (_user_string != NULL){
    delete _user_string;
    _user_string = NULL;
  }
}
long WSCform::_device_initialize(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  char pstyle = getPixmapStyle();
  dev->setVisible(False);
  if (getXOffsetPtr() == NULL){
    dev->setValue(WSDEV_X,(void*)&_x);
  }else{
    short ox = _x + *(getXOffsetPtr());
    dev->setValue(WSDEV_X,(void*)&ox);
  }
  if (getYOffsetPtr() == NULL){
    dev->setValue(WSDEV_Y,(void*)&_y);
  }else{
    short oy = _y + *(getYOffsetPtr());
    dev->setValue(WSDEV_Y,(void*)&oy);
  }
  dev->setValue(WSDEV_MOUSE_NO,(void*)&_mouse_no);
  dev->setValue(WSDEV_WIDTH,(void*)&_w);
  dev->setValue(WSDEV_HEIGHT,(void*)&_h);
  dev->setValue(WSDEV_BACKCOLOR,(void*)&_back_color);
  dev->setValue(WSDEV_BACK_PIXMAP,(void*)&_bp_color);
  dev->setValue(WSDEV_PIXMAP_STYLE,(void*)&pstyle); 
  dev->setEnableEventBit(WSEV_EXPOSE_BIT | WSEV_RESIZE_BIT);
  if (getVisible() != False){
    dev->setVisible(True);
  }
  WSCbase::_device_initialize();
  return WS_NO_ERR;
}
long WSCform::getObjectType(){
  return (WS_TYPE_MANAGER | WS_TYPE_FORM);
}
long WSCform::draw(){
dbprintf("WSCform::draw %s:%d %s begin..\n",__FILE__,__LINE__,getInstanceName());
  if (_no_refresh != False){
    WSCbase::update();
    setAbsoluteDraw(False);
dbprintf("WSCform::draw %s:%d %s no refresh..\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }
  if (getVisible() == False){
dbprintf("WSCform::draw %s:%d %s vis=False..\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
dbprintf("WSCform::draw %s:%d %s dev=NULL..\n",__FILE__,__LINE__,getInstanceName());
    return WS_ERR;
  }

  WSCbool absolute = getAbsoluteDraw(); 
  if (absolute == False  ){
    if ( dev->isExposed(0,0,_w,_h) == False ){
dbprintf("WSCform::draw %s:%d %s not exposed..\n",__FILE__,__LINE__,getInstanceName());
      return WS_NO_ERR;
    }
  }
  if (_update_resize != False){
    _update_resize = False;
    execResizeEvent();
  }

  if (_geometry_changed != False){
dbprintf("WSCform::draw %s:%d %s call _exec_child_adjust_for_anchors()..\n",__FILE__,__LINE__,getInstanceName());
    _exec_child_adjust_for_anchors();
  }

  if (WSGIappDev()->getExtGuiPolicySelected() != False){
    if (_ext_draw_proc == NULL){
      _ext_draw_proc = (void(*)(void*))WSGIappDev()->
                               getExtGuiPolicyProc("WSCform::draw");
    }
    if (_ext_draw_proc != NULL){
      WSCform_draw_struct st;
      st._this = this;
      st.dev = dev;
      st.x = _x;
      st.y = _y;
      st.width = _w;
      st.height = _h;
      st.shadow_thickness = _shadow_thick;
      st.shadow_type = _shadow_type;
      st.fore_color = _fore_color;
      st.back_color = _back_color;
      st.top_shadow_color = _ts_color;
      st.bottom_shadow_color = _bs_color;
      st.back_pixmap = _bp_color;
      st.gradation = _grad_no;
      st.gradation_margin = _grad_margin;
      _ext_draw_proc(&st);
      return WS_NO_ERR;
    }  
  }  

  long err = dev->beginDraw(0,0,_w,_h,absolute); 
  if (err != WS_NO_ERR){
dbprintf("WSCform::draw %s:%d %s dev not ready..\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }
  short ex = 0;
  short ey = 0;
  WSCushort ew = _w;
  WSCushort eh = _h;
  if (absolute == False){
    dev->getExposedArea(&ex,&ey,&ew,&eh);
  }
  WSCbase::update();
  setAbsoluteDraw(False);


  if (_bp_color == -1){
    if (_grad_no == 0){
      dev->setForeColor(_back_color);
      dev->drawFillRect(0,0,_w,_h);
      if ((WSGIappDev()->getGuiPolicy() & WS_POLICY_AQUA) != 0 &&
           _bp_color == -1){
        if (_a1_color == -1){
          WSGFgetShadowColor(_back_color,&_a1_color,&_a2_color,&_a3_color);
        }
        WSGFdrawStripes(dev,_w,_h,_a1_color,_a2_color,_a3_color);
      }
      dev->setForeColor(_back_color);

    }else{
      dev->drawGradation(_grad_no,_ts_color,_back_color,_bs_color,0,0,_w,_h,_grad_margin);
    }
  }

  if (getDotMode() == True){
    dev->setForeColor(_fore_color);
    long i,j;
    for(i=0; i<_w; i+=10){
      for(j=0; j<_h; j+=10){
        if (ex < i+1 && i < ex+ ew+1 &&
            ey < j+1 && j < ey+ eh+1 ){
          dev->drawFillRect(i,j,1,1);
        }
      }
    }
  }

  WSGFdrawShadow(dev,_shadow_type,_shadow_thick,_fore_color,_ts_color,_bs_color,_back_color,0,0,_w,_h);
  dev->endDraw();
  return WS_NO_ERR;
}
void WSCform::_exec_child_adjust_for_anchors(){
  if (adjustAnchor() != False){
    if (_geometry_changed != False){
      WSClistData children = getChildren();
      long num = children.getNum();
      long i;
      for(i=0; i<num; i++){
        WSCbase* child = (WSCbase*)children[i];
        child->_adjust_for_anchors(_w,_h);
        if (getPixmapStyle() == WS_DYNAMIC_PIXMAP){
          if (child->isNeedUpdate() != False){
            if ((long)child->getUserData("anchor update..") == 0){
              child->setUserData("anchor update..",(void*)1);
              child->update();
              child->setUserData("anchor update..",(void*)0);
            }
          }
        }
      } 
    }
  }
}

void WSCform::update(){
  if (isNeedUpdate() != False){
    WSDdev* dev = getowndev();
    if (dev != NULL){
      if (getXOffsetPtr() != NULL){
        short ox = _x + *(getXOffsetPtr());
        short dx;
        dev->getValue(WSDEV_X,&dx);
        if (ox != dx){
          dev->setValue(WSDEV_X,&ox);
        }
      }
      if (getYOffsetPtr() != NULL){
        short oy = _y + *(getYOffsetPtr());
        short dy;
        dev->getValue(WSDEV_Y,&dy);
        if (oy != dy){
          dev->setValue(WSDEV_Y,&oy);
        }
      }
    }
    if (_update_resize != False){
      _update_resize = False;
      execResizeEvent();
    }
    _exec_child_adjust_for_anchors();
    setAbsoluteDraw(True);
    redraw();
    WSCbase::update();
  }
}
long WSCform::clear(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  if (getVisible() == False){
    return WS_ERR;
  }
  long er = dev->beginDraw(0,0,_w,_h,True);
  if (er != WS_NO_ERR){
    return WS_NO_ERR;
  }
  dev->clearArea(0,0,_w,_h,False);
  dev->endDraw();
  return WS_NO_ERR;
}

long WSCform::redraw(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  if (getVisible() == False){
    return WS_ERR;
  }
  long er = dev->beginDraw(0,0,_w,_h,True);
  if (er != WS_NO_ERR){
    return WS_NO_ERR;
  }
  dev->clearArea(0,0,_w,_h,True);
  dev->endDraw();
  return WS_NO_ERR;
}

long WSCform::cdraw(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  if (getVisible() == False){
    return WS_ERR;
  }
  if (getPixmapStyle() != WS_DIRECT_WINDOW){
    redraw();
  }else{
    WSCrect area; 
    area.x = _x;
    area.y = _y;
    area.width = _w;
    area.height = _h;

    short bx,by;
    WSCushort bw,bh; 
    dev->getExposedArea(&bx,&by,&bw,&bh);
    dev->setExposedArea(_x,_y,_w,_h);
    dev->execEvent(WSEV_EXPOSE,&area);
    dev->setExposedArea(bx,by,bw,bh);
  }
  return WS_NO_ERR;
}
void WSCform::execResizeEvent(){
  WSCrect rect;
  rect.x = _x;
  rect.y = _y;
  rect.width = _w;
  rect.height = _h;
  execEventProc(WSEV_RESIZE,(void*)&rect);
}
void WSCform::_adjust_for_anchors(WSCushort w,WSCushort h){
  long resized = False;
  if (w > 0){
    if (_anchor_left_use == 0){
      if (_anchor_right_use != 0){
        long nx = w - _anchor_right - _w;
        _anchor_right_use = False;
        setProperty(WSNx,nx);
        _anchor_right_use = True;
      }
    }else{
      if (_anchor_right_use != 0){
        _anchor_left_use = False;
        _anchor_right_use = False;
        if (w < _anchor_right + _anchor_left){
          setProperty(WSNwidth,1);
          resized = True;
        }else{
          setProperty(WSNx,_anchor_left);
          setProperty(WSNwidth,w - _anchor_right - _anchor_left);
          resized = True;
        }
        _anchor_left_use = True;
        _anchor_right_use = True;
      }else{
        if (_anchor_left != _x){
          setProperty(WSNx,_anchor_left);
        }
      }
    }
    needUpdate();
    setAbsoluteDraw(True);
  }
  if (h > 0){
    if (_anchor_top_use == 0){
      if (_anchor_bottom_use != 0){
        long ny = h - _anchor_bottom - _h;
        _anchor_bottom_use = False;
        setProperty(WSNy,ny);
        _anchor_bottom_use = True;
      }
    }else{
      if (_anchor_bottom_use != 0){
        _anchor_top_use = False;
        _anchor_bottom_use = False;
        clear();
        if (h < _anchor_bottom + _anchor_top){
          setProperty(WSNheight,1);
          resized = True;
        }else{
          setProperty(WSNy,_anchor_top);
          setProperty(WSNheight,h - _anchor_top - _anchor_bottom);
          resized = True;
        }
        _anchor_top_use = True;
        _anchor_bottom_use = True;
      }else{
        if (_anchor_top != _y){
          setProperty(WSNy,_anchor_top);
        }
      }
    }
    needUpdate();
    setAbsoluteDraw(True);
  }
  if (resized != False){
    WSCrect rect;
    rect.x = _x;
    rect.y = _y;
    rect.width = _w;
    rect.height = _h;
    execEventProc(WSEV_RESIZE,&rect);
  }
}
long WSCform::execEventProc(long ev, void* data){
  if (ev == WSEV_EXPOSE){
    if (data == NULL){
      WSCrect area;
      area.setRect(0,0,_w,_h);
      onExpose(&area);
      draw();
      if (_expose_op == 1){
        execProcedure(ev);
      }
      return WS_NO_ERR;
    }else{
      WSCrect* area = (WSCrect*)data;
      onExpose(area);
      draw();
      if (_expose_op == 1){
        execProcedure(ev);
      }
    }
    return WS_NO_ERR;
  }
  return WSCbase::execEventProc(ev,data);
}
long WSCform::getPixmapStyle(){
#ifndef BTRON
#ifndef TE
  return _pixmap_style;
#else
  return WS_DYNAMIC_PIXMAP;
#endif
#else
  return WS_DYNAMIC_PIXMAP;
#endif
}

void(*WSCform::_ext_draw_proc)(void*) = NULL;
WSCstring WSCform::_policy_name;

void WSCform::onGuiPolicyChange(long policy){
  WSCbase::onGuiPolicyChange(policy);
  if (WSGIappDev()->getExtGuiPolicySelected() == False){
    _ext_draw_proc = NULL;
  }else{
    if (!strcmp((char*)_policy_name,(char*)WSGIappDev()->getExtGuiPolicyName())){
    }else{
      _ext_draw_proc = (void(*)(void*))WSGIappDev()->getExtGuiPolicyProc("WSCform::draw");
    }
  }
  needUpdate();
  setAbsoluteDraw(True);
  redraw();
}

