//
// 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 <WSCwindow.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSDdev.h>
#include <WSCbaseList.h>
#include <WSCcolorSet.h>
#include <WSDappDev.h>
#include <WSDtimer.h>

WSMFguiClassInitialize(WSCwindow,WSCbase);
WSMFversion(WSCwindow,WSCbase);
WSMFdefineUseDevice(WSCwindow,windowDev)
void _set_active_instance(WSCbase* win);
void (*WSCwindow::_exit_handler)() = NULL;

WSClistData* WSCwindow::_workwindow_list = NULL;
WSClistData* WSCwindow::getWorkWindowList(){
  if (_workwindow_list == NULL){
    _workwindow_list = new WSClistData();
  }
  return _workwindow_list;
}

WSCwindow::WSCwindow(WSCbase* base,char* objname):
                WSCbase(base,objname){

  getWorkWindowList()->add(this);

  _title_string = NULL;
  _user_string  = NULL;
  _user_value   = 0;
  _x            = 0;
  _y            = 0;
  _w            = 100;
  _h            = 30;
  _shadow_thick = 0;
//  _fg_no        = WSGFcolor("black");
//  _bg_no        = WSGFcolor("gray85");
//  _ts_no        = WSGFcolor("gray95");
//  _bs_no        = WSGFcolor("gray55");
  _fg_no        = WS_DF_FORECOLOR;
  _bg_no        = WS_DF_BACKCOLOR;
  _ts_no        = WS_DF_TOPSHADOWCOLOR;
  _bs_no        = WS_DF_BOTTOMSHADOWCOLOR;
  _bp_no        = -1;
  _title_bar    = WS_FULL_TITLE;
  _shadow_type  = 0;
  _grad_no     = 0;
  _grad_margin   = 0;
  _vis          = False;
  _sensitive    = True;
  _pixmap_style = WS_DIRECT_WINDOW;
  _unique       = False;
  _group_name   = NULL;
  _mouse_no     = 0;
  _parent_vis_init = False;
  _parent_vis   = False;
  _exit         = False;
  _update_resize = False;
  _indicator = True;
  _margin = 2;
  _margin_left = 2;
  _bar_thick = 16;
  _emboss = False;
  _a1_color = -1;
  _a2_color = -1;
  _a3_color = -1;
  _vis_ch_sequence = False;

  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCwindow);

    WSMFpropertyCreate(WSNname,char*, _instance_name, WSSname);
    WSMFpropertyCreate(WSNtitleString,char*, _title_string, WSStitleString);
    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, _fg_no,WSSforeColor );
    WSMFpropertyCreate(WSNbackColor,  short, _bg_no,WSSbackColor );
    WSMFpropertyCreate(WSNtopShadowColor,short,_ts_no,WSStopShadowColor );
    WSMFpropertyCreate(WSNbottomShadowColor,short,_bs_no,WSSbottomShadowColor  );
    WSMFpropertyCreate(WSNbackPixmap, short, _bp_no,WSSbackPixmap  );
    WSMFpropertyCreate(WSNtitleBar, char, _title_bar,WSStitleBar );
      WSMFpropertySetSelection(WSRtitleBar,WSRtitleBarD);
    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( WSNgroup, char*, _group_name,WSSgroup  );
    WSMFpropertyCreate( WSNunique,  WSCbool, _unique,WSSunique  );
      WSMFpropertySetSelection(WSRbool3,WSRbool3D);
    WSMFpropertyCreate( WSNmouse, WSCushort,   _mouse_no,WSSmouse  );

    WSMFpropertyCreate(WSNgradation,  WSCuchar,  _grad_no,WSSgradation);
      WSMFpropertySetSelection(WSRgradation,WSRgradationD);
    WSMFpropertyCreate(WSNgradationMargin,WSCuchar,_grad_margin,WSSgradationMargin);
    WSMFpropertyCreate( WSNexit,  WSCbool, _exit,WSSexit  );
      WSMFpropertySetSelection(WSRbool3,WSRbool3D);
    WSMFpropertyCreate( WSNindicatorOn,  WSCbool, _indicator,WSSindicatorOn  );
      WSMFpropertySetSelection(WSRbool3,WSRbool3D);
    WSMFpropertyCreate( WSNmargin,  WSCuchar, _margin,WSSmargin  );
    WSMFpropertyCreate( WSNmarginLeft,  WSCushort, _margin_left,WSSmarginLeft  );
    WSMFpropertyCreate( WSNemboss,  WSCbool, _emboss,WSSemboss  );
      WSMFpropertySetSelection(WSRbool3,WSRbool3D);
    WSMFpropertyCreate( WSNbarThickness,  WSCuchar, _bar_thick,WSSbarThickness  );
    WSMFpropertyCreate(WSNexport,WSCbool,_export_,WSSexport);
    WSMFpropertySetSelection(WSRbool1, WSRbool1D);

      WSMFaddTrigger(WSEV_INITIALIZE  );
      WSMFaddTrigger(WSEV_FOCUS_CH  );
      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_RESIZE      );
      WSMFaddTrigger(WSEV_ACTIVATE    );
      WSMFaddTrigger(WSEV_EXPOSE      );

      WSMFaddExtTrigger(WSEV_EXIT,"EXIT" );

  WSMFpropertyCreateEnd

}

WSMFproperty(WSCwindow, WSNname,char*,    _instance_name,WSGFstrdup("")); 
WSMFproperty(WSCwindow, WSNtitleString,char*,    _title_string,WSGFstrdup("")); 
WSMFproperty(WSCwindow, WSNuserString, char*,    _user_string ,WSGFstrdup("")); 
WSMFproperty(WSCwindow, WSNuserValue,  long,     _user_value  ,0      ); 
WSMFproperty(WSCwindow, WSNx,          short,    _x           ,0    );
WSMFproperty(WSCwindow, WSNy,          short,    _y           ,0    );
WSMFproperty(WSCwindow, WSNwidth,      WSCushort,_w           ,100    );
WSMFproperty(WSCwindow, WSNheight,     WSCushort,_h           ,30     );
WSMFproperty(WSCwindow, WSNshadowThickness,WSCuchar,_shadow_thick,0      );
//WSMFproperty(WSCwindow, WSNforeColor,  short,    _fg_no ,WSGFcolor("black"));
//WSMFproperty(WSCwindow, WSNbackColor,  short,    _bg_no ,WSGFcolor("gray85"));
//WSMFproperty(WSCwindow, WSNtopShadowColor,  short,_ts_no ,WSGFcolor("gray95"));
//WSMFproperty(WSCwindow, WSNbottomShadowColor, short,_bs_no ,WSGFcolor("gray55"));
WSMFproperty(WSCwindow, WSNforeColor,  short,    _fg_no ,WS_DF_FORECOLOR);
WSMFproperty(WSCwindow, WSNbackColor,  short,    _bg_no ,WS_DF_BACKCOLOR);
WSMFproperty(WSCwindow, WSNtopShadowColor,  short,_ts_no ,WS_DF_TOPSHADOWCOLOR);
WSMFproperty(WSCwindow, WSNbottomShadowColor, short,_bs_no ,WS_DF_BOTTOMSHADOWCOLOR);
WSMFproperty(WSCwindow, WSNbackPixmap,        short,_bp_no    ,-1    );
WSMFproperty(WSCwindow, WSNtitleBar,   char,     _title_bar    ,WS_FULL_TITLE  );
WSMFproperty(WSCwindow, WSNshadowType, char,     _shadow_type  ,0      );
WSMFproperty(WSCwindow, WSNvis,        WSCbool,  _vis   ,False   );
WSMFproperty(WSCwindow, WSNdet,        WSCbool,  _sensitive ,True  );
WSMFproperty(WSCwindow, WSNpixmapStyle,WSCuchar, _pixmap_style ,WS_DIRECT_WINDOW);
WSMFproperty(WSCwindow, WSNunique,  WSCbool,  _unique       ,False);
WSMFproperty(WSCwindow, WSNgroup,   char*,    _group_name   ,WSGFstrdup(""));
WSMFproperty(WSCwindow, WSNmouse,   WSCushort,     _mouse_no     ,0);
WSMFproperty(WSCwindow, WSNgradation, WSCuchar, _grad_no   ,0);
WSMFproperty(WSCwindow, WSNgradationMargin, WSCuchar, _grad_margin ,0);
WSMFproperty(WSCwindow, WSNexit,  WSCbool,  _exit       ,False);
WSMFproperty(WSCwindow, WSNindicatorOn,  WSCbool,  _indicator   ,True);
WSMFproperty(WSCwindow, WSNmargin,  WSCuchar,  _margin       ,2);
WSMFproperty(WSCwindow, WSNmarginLeft,  WSCushort,  _margin_left       ,2);
WSMFproperty(WSCwindow, WSNemboss,  WSCbool,  _emboss       ,False);
WSMFproperty(WSCwindow, WSNbarThickness,  WSCuchar,  _bar_thick   ,16);
WSMFproperty(WSCwindow, WSNexport,  WSCbool,  _export_   ,False);

void WSCwindow::setWorkWSNemboss(WSCbool data){}
void WSCwindow::getWorkWSNemboss(WSCbool* data){}

void WSCwindow::setWorkWSNbarThickness(WSCuchar data){}
void WSCwindow::getWorkWSNbarThickness(WSCuchar* data){}

void WSCwindow::setWorkWSNindicatorOn(WSCbool data){}
void WSCwindow::getWorkWSNindicatorOn(WSCbool* data){}

void WSCwindow::setWorkWSNmargin(WSCuchar data){}
void WSCwindow::getWorkWSNmargin(WSCuchar* data){}

void WSCwindow::setWorkWSNmarginLeft(WSCushort data){}
void WSCwindow::getWorkWSNmarginLeft(WSCushort* data){}

void WSCwindow::setWorkWSNname(char* data){}
void WSCwindow::getWorkWSNname(char** data){}

void WSCwindow::setWorkWSNtitleString(char* data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_TITLE_STRING,(void*)data);
  }
}

void WSCwindow::getWorkWSNtitleString(char** ){
}

void WSCwindow::setWorkWSNuserString(char* ){
}

void WSCwindow::getWorkWSNuserString(char** ){
}

void WSCwindow::setWorkWSNuserValue(long ){
}

void WSCwindow::getWorkWSNuserValue(long* ){
}

void WSCwindow::setWorkWSNx(short data){
  if (getPropertyEditMode() != False){
    long tmp =(long)data;
    setUserData("WW-X",(void*)tmp);
    return;
  }
  if (_initialized != False && _dev != NULL){
      _dev->setValue(WSDEV_X,(void*)&data);
      _geometry_changed = True;
  }
}
void WSCwindow::getWorkWSNx(short* data){
  if (getPropertyEditMode() != False){
    long tmp =(long)getUserData("WW-X");
    short val = (short)tmp;
    *data = val;
  }
}
void WSCwindow::setWorkWSNy(short data){
  if (getPropertyEditMode() != False){
    long tmp =(long)data;
    setUserData("WW-Y",(void*)tmp);
  }
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_Y,(void*)&data);
    _geometry_changed = True;
  }
}
void WSCwindow::getWorkWSNy(short* data){
  if (getPropertyEditMode() != False){
    long tmp =(long)getUserData("WW-Y");
    short val = (short)tmp;
    *data = val;
  }
}
void WSCwindow::setWorkWSNwidth(WSCushort data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_WIDTH,(void*)&data);
  }
  _geometry_changed = True;
  _update_resize = True;
  adjustForm();
}
void WSCwindow::getWorkWSNwidth(WSCushort* ){}
void WSCwindow::setWorkWSNheight(WSCushort data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_HEIGHT,(void*)&data);
  }
  _geometry_changed = True;
  _update_resize = True;
  adjustForm();
}

void WSCwindow::getWorkWSNheight(WSCushort* ){}
void WSCwindow::setWorkWSNshadowThickness(WSCuchar ){}
void WSCwindow::getWorkWSNshadowThickness(WSCuchar* ){}
void WSCwindow::setWorkWSNforeColor(short ){}
void WSCwindow::getWorkWSNforeColor(short* ){}
void WSCwindow::setWorkWSNbackColor(short data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_BACKCOLOR,(void*)&data);
  }
  _a1_color = -1;
  _a2_color = -1;
  _a3_color = -1;
}
void WSCwindow::getWorkWSNbackColor(short* ){}
void WSCwindow::setWorkWSNtopShadowColor(short ){}
void WSCwindow::getWorkWSNtopShadowColor(short* ){}
void WSCwindow::setWorkWSNbottomShadowColor(short ){}
void WSCwindow::getWorkWSNbottomShadowColor(short* ){}
void WSCwindow::setWorkWSNbackPixmap(short data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_BACK_PIXMAP,(void*)&data);
  }
}

void WSCwindow::getWorkWSNbackPixmap(short* ){}
void WSCwindow::setWorkWSNtitleBar(char data){
  if (getPropertyEditMode() == False){
    if (_dev == NULL){
      return;
    }
    if (_initialized != False){
      char val = data;
      if (val == WS_NO_MANAGE){
        val = WS_NO_TITLE;
        WSCbool fl = True;
        _dev->setValue(WSDEV_NO_FRAME,(void*)&fl);
      }else{
        WSCbool fl = False;
        _dev->setValue(WSDEV_NO_FRAME,(void*)&fl);
      }
      _dev->setValue(WSDEV_TITLE_BAR,(void*)&val);
	}
  }else{
    long val = data;
    setUserData("WW-TITLEB",(void*)val);
    if (_dev == NULL){
      return;
    }
    WSCbool fl = False;
    _dev->setValue(WSDEV_NO_FRAME,(void*)&fl);
//    char dat = WS_ONLY_TITLE;
    char dat = WS_FULL_TITLE;
    _dev->setValue(WSDEV_TITLE_BAR,(void*)&dat);
  }
}

void WSCwindow::getWorkWSNtitleBar(char* data){
  if (getPropertyEditMode() != False){
    long tmp =(long)getUserData("WW-TITLEB");
    char fl = (char)tmp;
    *data = fl;
  }
}

void WSCwindow::setWorkWSNshadowType(char ){}
void WSCwindow::getWorkWSNshadowType(char* ){}
void WSCwindow::setWorkWSNvis(WSCbool data){
//printf("WSCwindow:setWorkWSNvis %s editmode=%d %d\n",getInstanceName(),getPropertyEditMode(),data);
  if (getPropertyEditMode() == False){
    setVisible( data );
  }else{
    _vis = _vis_bk;
    long val = (long)data;
    setUserData(WS_VIS,(void*)val);
  }
}

void WSCwindow::getWorkWSNvis(WSCbool* data){
//printf("WSCwindow::getWorkWSNvis %d\n",_vis);
  if (getPropertyEditMode() != False){
    long tmp = (long)getUserData(WS_VIS);
    WSCbool fl = (WSCbool)tmp;
//printf("WSCwindow::getWorkWSNvis ret=%d\n",fl);
    *data = fl;
  }
}
void WSCwindow::onEditModeChange(WSCbool fl){
//printf("WSCwindow::onEditModeChange %d\n",fl);
  WSCbase::onEditModeChange(fl);
  if (fl != False){
    long val;
    val = _x;
    setUserData("WW-X",(void*)val);
    val = _y;
    setUserData("WW-Y",(void*)val);

    if (_vis == False){
      setUserData(WS_VIS,(void*)0);
    }else{
      setUserData(WS_VIS,(void*)1);
    }
    if (_sensitive == False){
      setUserData(WS_DET,(void*)0);
    }else{
      setUserData(WS_DET,(void*)1);
    }
    val = _title_bar;
    setUserData("WW-TITLEB",(void*)val);
  }
}
void WSCwindow::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 WSCwindow::getWorkWSNdet(WSCbool* data){
  if (getPropertyEditMode() != False){
    long tmp = (long)getUserData(WS_DET);
    WSCbool fl = (WSCbool)tmp;
    *data = fl;
  }
}

void WSCwindow::setWorkWSNpixmapStyle(WSCuchar data){
  if (_initialized != False && _dev != NULL){
    _dev->setValue(WSDEV_PIXMAP_STYLE,(void*)&data);
  }
}
void WSCwindow::getWorkWSNpixmapStyle(WSCuchar* ){}
void WSCwindow::setWorkWSNunique(WSCbool){}
void WSCwindow::getWorkWSNunique(WSCbool* ){}
void WSCwindow::setWorkWSNgroup(char*){}
void WSCwindow::getWorkWSNgroup(char** ){}

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

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

long WSCwindow::initialize(){
  WSCbase::initialize();
  return WS_NO_ERR;
}

WSCwindow::~WSCwindow(){
  WSClistData* ghlist = (WSClistData*)getUserData("GH-LIST");
  if (ghlist != NULL){
    delete ghlist;
    setUserData("GH-LIST",(void*)0);
  }

  while(1){
    if (_children.getNum() == 0){
      break;
    }
    WSCbase* ch = (WSCbase*)_children.getData(0);
//printf("WSCwindow::~WSCwindow del ch=%s\n",ch->getInstanceName());
    delete ch;
  }

  if ( WSGFgetActiveWindow() == this){
    _set_active_instance(NULL);
  }
  getWorkWindowList()->del(this);
  if (_title_string != NULL){
    delete _title_string;
  }
  if (_user_string != NULL){
    delete _user_string;
  }
  if (_group_name != NULL){
    delete _group_name;
  }
}

void WSCwindow::setChildren(WSClistData& src){
  _children = src;
}
WSClistData& WSCwindow::getChildren(){
  return _children;
}

long WSCwindow::_device_initialize(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }

  if (getPropertyEditMode() == False){
    char val = _title_bar;
    if (_title_bar == WS_NO_MANAGE){
      char val = WS_NO_TITLE;
      _dev->setValue(WSDEV_TITLE_BAR,(void*)&val);
    }else{
      _dev->setValue(WSDEV_TITLE_BAR,(void*)&val);
    }
  }
  if (_title_bar == WS_NO_MANAGE && getPropertyEditMode() == False){
      WSCbool fl = True;
      dev->setValue(WSDEV_NO_FRAME,(void*)&fl);
  }else{
      WSCbool fl = False;
      dev->setValue(WSDEV_NO_FRAME,(void*)&fl);
  }

  dev->setValue(WSDEV_MOUSE_NO,(void*)&_mouse_no);
  dev->setValue(WSDEV_X,(void*)&_x);
  dev->setValue(WSDEV_Y,(void*)&_y);
  dev->setValue(WSDEV_WIDTH,(void*)&_w);
  dev->setValue(WSDEV_HEIGHT,(void*)&_h);
  dev->setValue(WSDEV_BACKCOLOR,(void*)&_bg_no);
  dev->setValue(WSDEV_BACK_PIXMAP,(void*)&_bp_no);

  char pixmap_style = getPixmapStyle();
  dev->setValue(WSDEV_PIXMAP_STYLE,(void*)&pixmap_style);
  if (_title_string != NULL){
    dev->setValue(WSDEV_TITLE_STRING,(void*)_title_string);
  }else{
    dev->setValue(WSDEV_TITLE_STRING,(void*)"");
  }

  dev->setEnableEventBit(WSEV_EXPOSE_BIT | WSEV_RESIZE_BIT);
  if (_parent != NULL){
    dev->setValue(WSDEV_POPUP_PARENT,(void*)_parent);
  }

  WSCbase::_device_initialize();
  return WS_NO_ERR;
}
void WSCwindow::onDefaultColorChange(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return;
  }
  dev->setValue(WSDEV_BACKCOLOR,(void*)&_bg_no);
}
long WSCwindow::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;
}
long WSCwindow::draw(){
dbprintf("WSCwindow::draw %s:%d %s begin..\n",__FILE__,__LINE__,getInstanceName());
  if (getVisible() == False){
dbprintf("WSCwindow::draw %s:%d %s vis=False\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
dbprintf("WSCwindow::draw %s:%d %s dev=NULL\n",__FILE__,__LINE__,getInstanceName());
    return WS_ERR;
  }
  WSCbool absolute = getAbsoluteDraw(); 
  if (absolute == False  ){
#if 0
    if (getDotMode() == False){
      if ( dev->isExposed(0,0,_w,_shadow_thick) == False &&
           dev->isExposed(0,0,_shadow_thick,_h) == False &&
           dev->isExposed(_w -_shadow_thick,0,_shadow_thick,_h) == False &&
           dev->isExposed(0,_h -_shadow_thick,_w,_shadow_thick) == False ){
        return WS_NO_ERR;
      }
    }else{
#endif
      if ( dev->isExposed(0,0,_w,_h) == False ){
dbprintf("WSCwindow::draw %s:%d %s not exposed\n",__FILE__,__LINE__,getInstanceName());
        return WS_NO_ERR;
      }
#if 0
    }
#endif
  }
  if (_update_resize != False){
    _update_resize = False;
    execResizeEvent();
  }

  if (_geometry_changed != False){
    _exec_child_adjust_for_anchors();
  }
  long err = dev->beginDraw(0,0,_w,_h,absolute);
  if (err != WS_NO_ERR){
dbprintf("WSCwindow::draw %s:%d %s 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_no == -1){
    if (_grad_no == 0){
      dev->setForeColor(_bg_no);
      dev->drawFillRect(0,0,_w,_h);
      if ((WSGIappDev()->getGuiPolicy() & WS_POLICY_AQUA) != 0 && _bp_no == -1){
        if (_a1_color == -1){
          WSGFgetShadowColor(_bg_no,&_a1_color,&_a2_color,&_a3_color);
        }
        WSGFdrawStripes(dev,_w,_h,_a1_color,_a2_color,_a3_color);
      }
      dev->setForeColor(_bg_no);
    }else{
      dev->drawGradation(_grad_no,_ts_no,_bg_no,_bs_no,0,0,_w,_h,_grad_margin);
    }
  }

  if (getDotMode() == True){
    dev->setForeColor(_fg_no);
    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);
        }
      }
    }
  }

  if (_shadow_thick > 0){
    WSGFdrawShadow(dev,_shadow_type,_shadow_thick,_fg_no,_ts_no,_bs_no,_bg_no,0,0,_w,_h);
  }
  long margin = _margin + _shadow_thick; 
  long margin2 = _margin_left + _shadow_thick; 
  long indicator = _indicator;
  if ((WSGIappDev()->getGuiPolicy() & WS_POLICY_WINDOWS) == 0){
    indicator = 0;
  }

  if (_emboss != 0 && margin *2 < _w && _bar_thick + margin < _h ){
    WSGFdrawShadow(dev,WS_SHADOW_IN,1,_fg_no,_ts_no,_bs_no,_bg_no,
            margin2,_h - _bar_thick - margin,_w - margin - margin2,_bar_thick);
    if (indicator != False){
      dev->setLineWidth(0);
      dev->setForeColor(_ts_no);
      dev->drawLine(_w - 12 - margin,_h -4 ,_w -4,_h -12 - margin);
      dev->drawLine(_w - 8 - margin,_h -4 ,_w -4,_h -8 - margin);
      dev->drawLine(_w - 4 - margin,_h -4 ,_w -4,_h -4 - margin);
      dev->setForeColor(_bs_no);
      dev->drawLine(_w - 11 - margin,_h -4 ,_w -4,_h -11 - margin);
      dev->drawLine(_w - 10 - margin,_h -4 ,_w -4,_h -10 - margin);
      dev->drawLine(_w - 7 - margin,_h -4 ,_w -4,_h -7 - margin);
      dev->drawLine(_w - 6 - margin,_h -4 ,_w -4,_h -6 - margin);
      dev->drawLine(_w - 3 - margin,_h -4 ,_w -4,_h -3 - margin);
      dev->drawLine(_w - 2 - margin,_h -4 ,_w -4,_h -2 - margin);
      dev->setForeColor(_bg_no);
      dev->drawLine(_w - 11 - margin,_h -3 ,_w -3,_h -3);
      dev->drawLine(_w - 3,_h -11 - margin ,_w -3,_h -3);
    }
  }else{
    if (indicator != False){
      dev->setLineWidth(0);
      dev->setForeColor(_ts_no);
      dev->drawLine(_w - 15 - margin,_h -3 ,_w -3,_h -15 - margin);
      dev->drawLine(_w - 11 - margin,_h -3 ,_w -3,_h -11 - margin);
      dev->drawLine(_w - 7 - margin,_h -3 ,_w -3,_h -7 - margin);
      dev->drawLine(_w - 3 - margin,_h -3 ,_w -3,_h -3 - margin);
      dev->setForeColor(_bs_no);
      dev->drawLine(_w - 14 - margin,_h -3 ,_w -3,_h -14 - margin);
      dev->drawLine(_w - 13 - margin,_h -3 ,_w -3,_h -13 - margin);
      dev->drawLine(_w - 10 - margin,_h -3 ,_w -3,_h -10 - margin);
      dev->drawLine(_w - 9 - margin,_h -3 ,_w -3,_h -9 - margin);
      dev->drawLine(_w - 6 - margin,_h -3 ,_w -3,_h -6 - margin);
      dev->drawLine(_w - 5 - margin,_h -3 ,_w -3,_h -5 - margin);
      dev->drawLine(_w - 2 - margin,_h -3 ,_w -3,_h -2 - margin);
      dev->drawLine(_w - 1 - margin,_h -3 ,_w -3,_h -1 - margin);
    }
  }




  dev->endDraw();
  return WS_NO_ERR;

}

void WSCwindow::onFocusChange(WSCbool fl){
  if (fl == True){
    _set_active_instance(this);
  }
}

void WSCwindow::onResize(WSCrect* area){
  WSCbool fl = 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;
  }
  adjustForm();
  if (getPropertyEditMode() != False){
    drawGriphand();
    if (fl != False){
      WSGFmarkChanged(this);
      WSCbase* prope = WSGIappPropertyEditor();
      if (prope != NULL){
        prope->setUserData(WS_GEOMETRY_UPDATE,(void*)1);
        prope->update();
      }
    }
  }
  if (fl != False){
    WSDdev* dev = getowndev();
    if (dev != NULL || getPixmapStyle() != WS_DIRECT_WINDOW){
      dev->setValue(WSDEV_WIDTH,&_w);
      dev->setValue(WSDEV_HEIGHT,&_h);
    }
    redraw();
  }

  if (fl != False){
    WSClistData children = getChildren();
    long num = children.getNum();
    long i;
    for(i=0; i<num; i++){
      WSCbase* child = (WSCbase*)children[i];
dbprintf("WSCwindow::onResize %s:%d %s child=%s call adjust_for_anchors\n",__FILE__,__LINE__,getInstanceName(),child->getInstanceName());
      child->_adjust_for_anchors(_w,_h);
      if (getPixmapStyle() == WS_DYNAMIC_PIXMAP){
        if (child->isNeedUpdate() != False){
          child->update();
dbprintf("WSCwindow::onResize %s:%d %s child=%s call update\n",__FILE__,__LINE__,getInstanceName(),child->getInstanceName());
        }
      }
    }
  }
}

void WSCwindow::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,&rect);
  }
  if (fl != False){
    char title_bar = _title_bar;
    if (getPropertyEditMode() != False){
      title_bar = WS_ONLY_TITLE;
    }else{
      if (title_bar == WS_NO_MANAGE){
        title_bar = WS_NO_TITLE;
      }
    }
    if (_unique != False && _group_name != NULL && strcmp(_group_name,"")){
      long num = getWorkWindowList()->getNum();
      long i;
      for(i = 0; i < num; i++){
        WSCwindow* tmp = (WSCwindow*)getWorkWindowList()->getData(i);
        if (tmp != this && !strcmp(tmp->_group_name,_group_name)){
          tmp->setVisible(False);
        }
      }
    }
  }else if (_exit != False){
    if (getPropertyEditMode() == False){
      if (_exit_handler != NULL){
        _exit_handler();
        execProcedure(WSEV_EXIT);
      }else{
        WSClistData* plist = getProcedureList();
        long i; 
        long num = plist->getNum();
        long no_exit = 0;
        for(i=0; i<num; i++){
          WSCprocedure* proc = (WSCprocedure*)plist->getData(i);
          if (WSEV_EXIT == proc->getTrigger()){
            no_exit = 1;
            execProcedure(WSEV_EXIT);
          }
        }
        if (no_exit == 0){
          if (WSGIappDev()->getMode() == WS_MODE_NORMAL){
            exit(0);
          }
        }
      }
    }
  }
}

void WSCwindow::setGlobalExitHandler(void(*hd)()){
  _exit_handler = hd;
}

void WSCwindow::update(){
  if (isNeedUpdate() != False){
//printf("WSCwindow::udpate %s\n",getInstanceName());
    if (_update_resize != False){
      _update_resize = False;
      execResizeEvent();
    }
    if (_geometry_changed != False){
      WSClistData children = getChildren();
      long num = children.getNum();
      long i;
      for(i=0; i<num; i++){
        WSCbase* child = (WSCbase*)children[i];
dbprintf("WSCwindow::onResize %s:%d %s child=%s call adjust_for_anchors\n",__FILE__,__LINE__,getInstanceName(),child->getInstanceName());
        child->_adjust_for_anchors(_w,_h);
        if (getPixmapStyle() == WS_DYNAMIC_PIXMAP){
          if (child->isNeedUpdate() != False){
            child->update();
dbprintf("WSCwindow::onResize %s:%d %s child=%s call update\n",__FILE__,__LINE__,getInstanceName(),child->getInstanceName());
          }
        }
      }
    }
    redraw();
    WSCbase::update();
  }
}

long WSCwindow::clear(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }

  if (getVisible() == False){
    return WS_ERR; //見えていなかったらクリアしない
  }

  long err = dev->beginDraw(0,0,_w,_h,True);
  if (err != WS_NO_ERR){
    return WS_NO_ERR;
  }

  dev->clearArea(0,0,_w,_h,False);
  dev->endDraw();

  return WS_NO_ERR;
}
long WSCwindow::redraw(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }

  if (getVisible() == False){
    return WS_ERR; //見えていなかったらクリアしない
  }

  long err = dev->beginDraw(0,0,_w,_h,True);
  if (err != WS_NO_ERR){
      return WS_NO_ERR;
  }
  dev->clearArea(0,0,_w,_h,True);
  dev->endDraw();

  return WS_NO_ERR;
}

long WSCwindow::getObjectType(){
  return (WS_TYPE_WINDOW | WS_TYPE_MANAGER | WS_TYPE_FORM);
}

long WSCwindow::setMapStatus(long val){
  if (_dev != NULL){
    _dev->setValue(WSDEV_MAP_STATUS,(void*)&val);
  }
  return WS_NO_ERR;
}

void WSCwindow::onParentVisibleChange(WSCbool fl){
  WSCbase::onParentVisibleChange(fl);
  if (fl != False){
    if (getPropertyEditMode() != False){
      setVisible(True);
    }
  }else{
    if (getPropertyEditMode() != False){
      setVisible(False);
    }
  }
}
static WSCbase* _active_window = NULL;
static WSCbase* _from_window = NULL;

void _set_active_instance(WSCbase* win){
  _from_window = _active_window;
  _active_window = win;
}

long WSGFsetActiveWindow(WSCbase* win){
  if ( win == NULL){  //NULLは解除の意味
    _from_window = _active_window;
    _active_window = NULL;
    return WS_NO_ERR;
  }

  if ( win->getObjectType() & WS_TYPE_WINDOW ){
    if (win->getVisible() == False){
      return WS_ERR;
    }
    //フォーカスのあたっているオブジェクトのフォーカスを外す
    WSCbase* focusobj = WSCbase::getFocusInstance();
    if (focusobj != NULL){
      focusobj->setFocus(False);
    }

    WSDdev* dev = win->getdev();
    if (dev == NULL){
      return WS_ERR;
    }
    char fl = True;
    dev->setValue(WSDEV_WIN_ACTIVE,(void*)&fl);
    //setValue() 後、デバイスの方からWinActive イベントが発生し、
    //WSCworkWindow などがそのイベントをもとに、_set_active_instance()
    //をして自分を登録してくる。
  }
  return WS_ERR;
}
WSCbase* WSGFgetPreActiveWindow(){
  return _from_window;
}

WSCbase* WSGFgetActiveWindow(){
  //ウィンドウがすでに消えていたら ACTIVE でない!
  if (_active_window != NULL && _active_window->getVisible() == False){
      _active_window = NULL;
  }
  return _active_window;
}
void WSCwindow::execResizeEvent(){
  WSCrect rect;
  rect.x = _x;
  rect.y = _y;
  rect.width = _w;
  rect.height = _h;
  execEventProc(WSEV_RESIZE,(void*)&rect);
}
void WSCwindow::adjustForm(){
}

void WSCwindow::_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];
dbprintf("WSCwindow::onResize %s:%d %s child=%s call adjust_for_anchors\n",__FILE__,__LINE__,getInstanceName(),child->getInstanceName());
        child->_adjust_for_anchors(_w,_h);
        if (getPixmapStyle() == WS_DYNAMIC_PIXMAP){
          if (child->isNeedUpdate() != False){
            if ((long)child->getUserData("anchor update..") == 0){
dbprintf("WSCwindow::onResize %s:%d %s child=%s call update\n",__FILE__,__LINE__,getInstanceName(),child->getInstanceName());
              child->setUserData("anchor update..",(void*)1);
              child->update();
              child->setUserData("anchor update..",(void*)0);
            }
          }
        }
      }
    }
  }
}

long WSCwindow::setWindowStatus(long state){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  return dev->setValue(WSDEV_WINDOW_STATE,&state);
}
long WSCwindow::getWindowStatus(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_WINDOW_NORMAL;
  }
  long val = WS_WINDOW_NORMAL;
  dev->getValue(WSDEV_WINDOW_STATE,&val);
  return val;
}

long WSCwindow::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 WSCwindow::getPixmapStyle(){
#ifndef BTRON
#ifndef TE
  return _pixmap_style;
#else
  return WS_DYNAMIC_PIXMAP;
#endif
#else
  return WS_DYNAMIC_PIXMAP;
#endif
}
void WSCwindow::_delay_visible(unsigned char,void* ptr){
  WSCbase* win = (WSCbase*)ptr;
  WSCbool fl = WSGIappObjectList()->existInstance(win);
  if (fl != False){
    win->WSCbase::setVisible(True);
  }
}
void WSCwindow::setVisible(WSCbool fl){
  if (_vis_ch_sequence != False){
    if (_vis == False && fl != False){
      WSGIappTimer()->addTriggerProc(_delay_visible,WS250MS,(WSCbase*)this);
      return;
    }
    WSCbase::setVisible(fl);
    return;
  }
  _vis_ch_sequence = True;
  WSCbase::setVisible(fl);
  _vis_ch_sequence = False;
}
