//
// 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 <WSCcomboBox.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSDdev.h>
#include <WSCwindow.h>
#include <WSClist.h>
#include <WSDappDev.h>
#include <WSDwindowDev.h>
#include <WSDmouse.h>
#include <WSDprivateTimer.h>
#include <WSCvarrow.h>
#include <WSCvifield.h>
#include <WSCblink.h>
#include <WSCfontSet.h>

WSMFguiClassInitialize(WSCcomboBox,WSCform);
WSMFversion(WSCcomboBox, WSCform);
#define WS_CM_BORDER 2
#define WS_STRETCH_HEIGHT 300
WSMFpropertyValueChange( WSCcomboBox, WSNshadowType , char,WS_SHADOW_IN);

WSCcomboBox::WSCcomboBox(WSCbase* base,char* objname):WSCform(base,objname){
  _register_focus_move();

  _menu_str = WSGFstrdup("item1,item2,item3");
  _max_height = 0;
  _win = NULL;
  _list = NULL;
  _btn = NULL;
  _if = NULL;
  _shadow_type = WS_SHADOW_IN;
  _bl_type = WS_FORE;
//  _bg_blink_color =  WSGFcolor("gray85");
//  _work_back_color =  WSGFcolor("gray85");
  _bg_blink_color = WS_DF_NWBACKCOLOR;
  _work_back_color = WS_DF_WORKBACKCOLOR;
  _rv_fl = False;
  _emboss = False;
  _use_pix = False;

  _max_length = WS_VLABEL_MAXLEN_DEFAULT;
  _label_string = WSGFstrdup("");
  _alignment_v = WS_CENTER;
  _alignment_h = WS_CENTER;
  _margin_top = 2;
  _margin_bottom = 2;
  _margin_left = 2;
  _margin_right = 2;
  _label_pixmap = -1;
  _blink_pixmap = -1;
  _font = (char)WSGIappFontSet()->getDefaultFontNo();

  _upname = NULL;
  _dwname = NULL;
  _lname = NULL;
  _rname = NULL;
  _rtname = NULL;
  _tbname = NULL;
  _btbname = NULL;
  _enable_focus_move = False;
  _cursor_adjust = True;
  _skip_mode = False;
  _columns = 20;
  _cur_pos = 0;
  _kanji_in = True;
  _icursor = True;
  _fspace = False;
  _item_height = 20;


  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCcomboBox);

    WSMFpropertyCreate(WSNmenuItems, char*, _menu_str,WSSmenuItems);
    WSMFpropertyCreate(WSNmaxHeight, WSCushort, _max_height,WSSmaxHeight);

    WSMFpropertyCreate(WSNreverseFlag, WSCbool, _rv_fl,WSSreverseFlag);
      WSMFpropertySetSelection(WSRbool4, WSRbool4D);
    WSMFpropertyCreate(WSNbackBlinkColor, short, _bg_blink_color,WSSbackBlinkColor);
    WSMFpropertyCreate(WSNworkBackColor,short,_work_back_color,WSSworkBackColor);
    WSMFpropertyCreate(WSNblinkType, WSCuchar, _bl_type,WSSblinkType);
      WSMFpropertySetSelection(WSRblinkType, WSRblinkTypeD);
    WSMFpropertyCreate(WSNemboss,           WSCbool,  _emboss,WSSemboss);
      WSMFpropertySetSelection(WSRbool1, WSRbool1D);
    WSMFpropertyCreate(WSNusePixmap,    WSCuchar,  _use_pix,WSSusePixmap);
      WSMFpropertySetSelection(WSRbool4, WSRbool4D);

    WSMFpropertyCreate(WSNlabelString,  char*,   _label_string,WSSlabelString);
    WSMFpropertyCreate(WSNalignmentV,   WSCuchar,   _alignment_v,WSSalignmentV );
      WSMFpropertySetSelection(WSRalignmentV, WSRalignmentVD);
    WSMFpropertyCreate(WSNalignmentH,   WSCuchar,   _alignment_h,WSSalignmentH);
      WSMFpropertySetSelection( WSRalignmentH, WSRalignmentHD);
    WSMFpropertyCreate(WSNmarginTop, WSCuchar, _margin_top,WSSmarginTop );
    WSMFpropertyCreate(WSNmarginBottom, WSCuchar, _margin_bottom,WSSmarginBottom);
    WSMFpropertyCreate(WSNmarginLeft, WSCuchar,_margin_left,WSSmarginLeft );
    WSMFpropertyCreate(WSNmarginRight,WSCuchar,_margin_right,WSSmarginRight);
    WSMFpropertyCreate(WSNmaxLength, WSCushort, _max_length,WSSmaxLength);
    WSMFpropertyCreate(WSNfont,  WSCuchar, _font,WSSfont  );
    WSMFpropertyCreate(WSNlabelPixmap, short, _label_pixmap,WSSlabelPixmap);
    WSMFpropertyCreate(WSNblinkPixmap, short, _blink_pixmap,WSSblinkPixmap);

    WSMFpropertyCreate(WSNcolumns,         WSCushort, _columns,WSScolumns );
    WSMFpropertyCreate(WSNcursorPos,  short, _cur_pos, WSScursorPos );
    WSMFpropertyCreate(WSNkanjiIn,  WSCbool, _kanji_in, WSSkanjiIn );
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);

    WSMFpropertyCreate(WSNinterCur, WSCbool, _icursor,WSSinterCur);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNupward, char*, _upname,WSSupward);
    WSMFpropertyCreate(WSNdownward,char*, _dwname,WSSdownward);
    WSMFpropertyCreate(WSNleftward,char*,_lname,WSSleftward);
    WSMFpropertyCreate(WSNrightward, char*,_rname,WSSrightward);
    WSMFpropertyCreate(WSNreturn,char*,_rtname,WSSreturn);
    WSMFpropertyCreate(WSNtab,char*,_tbname,WSStab);
    WSMFpropertyCreate(WSNbacktab,char*,_btbname,WSSbacktab);
    WSMFpropertyCreate(WSNenableFocusMove, WSCbool,_enable_focus_move,WSSenableFocusMove);
    WSMFpropertySetSelection(WSRbool1,WSRbool1D);

    WSMFpropertyCreate(WSNfillSpace, WSCbool, _fspace,WSSfillSpace);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNcursorAdjust,WSCbool,_cursor_adjust,WSScursorAdjust);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNifieldSkipMode,WSCbool,_skip_mode,WSSifieldSkipMode );
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNitemHeight,  WSCuchar, _item_height,WSSitemHeight  );

    WSMFpropertyValueChangeDef( WSCcomboBox,WSNshadowType ,char);
    WSMFpropertyValueChangeDef( WSCcomboBox,WSNshadowType ,char);

    WSMFaddTrigger(WSEV_VALUE_CH    );
    WSMFaddTrigger(WSEV_ACTIVATE    );
    WSMFaddTrigger(WSEV_KEY_PRESS    );
    WSMFaddTrigger(WSEV_KEY_RELEASE   );
    WSMFaddTrigger(WSEV_KEY_HOOK   );

  WSMFpropertyCreateEnd
}
WSMFproperty(WSCcomboBox, WSNmenuItems,  char*, _menu_str, WSGFstrdup("item1,item2,item3"));
WSMFproperty(WSCcomboBox, WSNmaxHeight,  WSCushort, _max_height,       0);

WSMFproperty(WSCcomboBox, WSNblinkType,         WSCuchar,       _bl_type, WS_FORE          );
//WSMFproperty(WSCcomboBox, WSNworkBackColor,    short,          _work_back_color, WSGFcolor("gray85"));
WSMFproperty(WSCcomboBox, WSNworkBackColor, short, _work_back_color,WS_DF_NWBACKCOLOR);
//WSMFproperty(WSCcomboBox, WSNbackBlinkColor,    short,          _bg_blink_color, WSGFcolor("gray85"));
WSMFproperty(WSCcomboBox, WSNbackBlinkColor, short, _bg_blink_color,WS_DF_WORKBACKCOLOR);
WSMFproperty(WSCcomboBox, WSNreverseFlag,       WSCbool,        _rv_fl, False              );
WSMFproperty(WSCcomboBox, WSNemboss,            WSCbool,        _emboss, False             );
WSMFproperty(WSCcomboBox, WSNusePixmap,         WSCuchar,       _use_pix,       False      );
WSMFproperty(WSCcomboBox, WSNlabelString, char*,    _label_string,  WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNalignmentV,  WSCuchar, _alignment_v,   WS_CENTER     );
WSMFproperty(WSCcomboBox, WSNalignmentH,  WSCuchar, _alignment_h,   WS_CENTER     );
WSMFproperty(WSCcomboBox, WSNmarginTop,   WSCuchar,_margin_top,    2             );
WSMFproperty(WSCcomboBox, WSNmarginBottom,WSCuchar,_margin_bottom, 2             );
WSMFproperty(WSCcomboBox, WSNmarginLeft,  WSCuchar,_margin_left,   2             );
WSMFproperty(WSCcomboBox, WSNmarginRight, WSCuchar,_margin_right,  2             );
WSMFproperty(WSCcomboBox, WSNmaxLength,   WSCushort,_max_length,    WS_VLABEL_MAXLEN_DEFAULT );
WSMFproperty(WSCcomboBox, WSNfont,        WSCuchar, _font,(char)WSGIappFontSet()->getDefaultFontNo());
WSMFproperty(WSCcomboBox, WSNlabelPixmap,  short,   _label_pixmap,  -1  );
WSMFproperty(WSCcomboBox, WSNblinkPixmap,  short,   _blink_pixmap,  -1  );
WSMFproperty(WSCcomboBox, WSNcolumns,   WSCushort, _columns,   20  );
WSMFproperty(WSCcomboBox, WSNcursorPos,  short,          _cur_pos,0      );
WSMFproperty(WSCcomboBox, WSNkanjiIn,  WSCbool,    _kanji_in,  True   );
WSMFproperty(WSCcomboBox, WSNinterCur, WSCbool,    _icursor, True  );
WSMFproperty(WSCcomboBox, WSNenableFocusMove, WSCbool,    _enable_focus_move, False );
WSMFproperty(WSCcomboBox, WSNupward,    char*,   _upname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNdownward, char*,   _dwname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNleftward,   char*,   _lname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNrightward,  char*,   _rname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNreturn, char*,   _rtname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNtab, char*,   _tbname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNbacktab, char*,   _btbname, WSGFstrdup(""));
WSMFproperty(WSCcomboBox, WSNfillSpace,   WSCbool,    _fspace,    False );
WSMFproperty(WSCcomboBox, WSNcursorAdjust,WSCbool,    _cursor_adjust, True );
WSMFproperty(WSCcomboBox, WSNifieldSkipMode, WSCbool,  _skip_mode,     False );
WSMFproperty(WSCcomboBox, WSNitemHeight,     WSCuchar,  _item_height, 20);

void WSCcomboBox::setWorkWSNdet(WSCbool fl){
  WSCform::setWorkWSNdet(fl);
  _if->setPropertyV(WSNdet,fl);
}
void WSCcomboBox::setWorkWSNupward(char* data){
  _if->setPropertyV(WSNupward,data);
}
void WSCcomboBox::getWorkWSNupward(char**){}
void WSCcomboBox::setWorkWSNdownward(char* data){
  _if->setPropertyV(WSNdownward,data);
}
void WSCcomboBox::getWorkWSNdownward(char**){}
void WSCcomboBox::setWorkWSNleftward(char* data){
  _if->setPropertyV(WSNleftward,data);
}
void WSCcomboBox::getWorkWSNleftward(char**){}
void WSCcomboBox::setWorkWSNrightward(char* data){
  _if->setPropertyV(WSNrightward,data);
}
void WSCcomboBox::getWorkWSNrightward(char**){}
void WSCcomboBox::setWorkWSNreturn(char* data){
  _if->setPropertyV(WSNreturn,data);
}
void WSCcomboBox::getWorkWSNreturn(char**){}
void WSCcomboBox::setWorkWSNtab(char* data){
  _if->setPropertyV(WSNtab,data);
}
void WSCcomboBox::getWorkWSNtab(char**){}
void WSCcomboBox::setWorkWSNbacktab(char* data){
  _if->setPropertyV(WSNbacktab,data);
}
void WSCcomboBox::getWorkWSNbacktab(char**){}

void WSCcomboBox::setWorkWSNcolumns(WSCushort data){
  _if->setPropertyV(WSNcolumns,data);
}
void WSCcomboBox::getWorkWSNcolumns(WSCushort*){}
void WSCcomboBox::setWorkWSNcursorPos(short data){
  _if->setPropertyV(WSNcursorPos,data);
}
void WSCcomboBox::getWorkWSNcursorPos(short*){}
void WSCcomboBox::setWorkWSNkanjiIn(WSCbool data){
  _if->setPropertyV(WSNkanjiIn,data);
}
void WSCcomboBox::getWorkWSNkanjiIn(WSCbool*){}
void WSCcomboBox::setWorkWSNinterCur(WSCbool fl){
  _if->setPropertyV(WSNinterCur,fl);
}
void WSCcomboBox::getWorkWSNinterCur(WSCbool*){}
void WSCcomboBox::setWorkWSNenableFocusMove(WSCbool data){
  _if->setPropertyV(WSNenableFocusMove,data);
}
void WSCcomboBox::getWorkWSNenableFocusMove(WSCbool*){}

void WSCcomboBox::setWorkWSNfillSpace(WSCbool fl){
  _if->setPropertyV(WSNfillSpace,fl);
}
void WSCcomboBox::getWorkWSNfillSpace(WSCbool*){}
void WSCcomboBox::setWorkWSNcursorAdjust(WSCbool data){
  _if->setPropertyV(WSNcursorAdjust,data);
}
void WSCcomboBox::getWorkWSNcursorAdjust(WSCbool*){}
void WSCcomboBox::setWorkWSNifieldSkipMode(WSCbool data){
  _if->setPropertyV(WSNifieldSkipMode,data);
}
void WSCcomboBox::getWorkWSNifieldSkipMode(WSCbool*){}

void WSCcomboBox::setWorkWSNmenuItems(char*){}
void WSCcomboBox::getWorkWSNmenuItems(char**){}
void WSCcomboBox::setWorkWSNmaxHeight(WSCushort){}
void WSCcomboBox::getWorkWSNmaxHeight(WSCushort*){}

void WSCcomboBox::setWorkWSNblinkType(WSCuchar data){
  _if->setPropertyV(WSNblinkType,data);
}
void WSCcomboBox::getWorkWSNblinkType(WSCuchar*){}

void WSCcomboBox::setWorkWSNworkBackColor(short data){
  _if->setPropertyV(WSNbackColor,data);
}
void WSCcomboBox::getWorkWSNworkBackColor(short* data){}

void WSCcomboBox::setWorkWSNbackBlinkColor(short data){
  _if->setPropertyV(WSNbackBlinkColor,data);
}
void WSCcomboBox::getWorkWSNbackBlinkColor(short*){}
void WSCcomboBox::setWorkWSNreverseFlag(WSCbool fl){
  _if->setPropertyV(WSNreverseFlag,fl);
}
void WSCcomboBox::getWorkWSNreverseFlag(WSCbool*){}
void WSCcomboBox::setWorkWSNemboss(WSCbool fl){
  _if->setPropertyV(WSNemboss,fl);
}
void WSCcomboBox::getWorkWSNemboss(WSCbool*){}

void WSCcomboBox::setWorkWSNusePixmap(WSCuchar fl) {
  _if->setPropertyV(WSNusePixmap,fl);
}
void WSCcomboBox::getWorkWSNusePixmap(WSCuchar*){}
void WSCcomboBox::setWorkWSNlabelString(char* data){
  _if->setPropertyV(WSNlabelString,data);
}
void WSCcomboBox::getWorkWSNlabelString(char** str){
  if (_label_string != NULL){
    delete _label_string;
  }
  _label_string = WSGFstrdup(_if->getProperty(WSNlabelString));
  *str = _label_string;
}
void WSCcomboBox::setWorkWSNalignmentV(WSCuchar data){
  _if->setPropertyV(WSNalignmentV,data);
}
void WSCcomboBox::getWorkWSNalignmentV(WSCuchar*){}
void WSCcomboBox::setWorkWSNmarginTop(WSCuchar data){
  _if->setPropertyV(WSNmarginTop,data);
}
void WSCcomboBox::getWorkWSNmarginTop(WSCuchar*){}
void WSCcomboBox::setWorkWSNmarginBottom(WSCuchar data){
  _if->setPropertyV(WSNmarginBottom,data);
}
void WSCcomboBox::getWorkWSNmarginBottom(WSCuchar*){}
void WSCcomboBox::setWorkWSNalignmentH(WSCuchar data){
  _if->setPropertyV(WSNalignmentH,data);
}
void WSCcomboBox::getWorkWSNalignmentH(WSCuchar*){}
void WSCcomboBox::setWorkWSNmarginLeft(WSCuchar data){
  _if->setPropertyV(WSNmarginLeft,data);
}
void WSCcomboBox::getWorkWSNmarginLeft(WSCuchar*){}
void WSCcomboBox::setWorkWSNmarginRight(WSCuchar data){
  _if->setPropertyV(WSNmarginRight,data);
}
void WSCcomboBox::getWorkWSNmarginRight(WSCuchar*){}
void WSCcomboBox::setWorkWSNmaxLength(WSCushort len) {
  if (len > 1024) {
    _max_length = 1024;
  }
  _if->setPropertyV(WSNmaxLength,_max_length);
}

void WSCcomboBox::getWorkWSNmaxLength(WSCushort*){}
void WSCcomboBox::setWorkWSNfont(WSCuchar data){
  _if->setPropertyV(WSNfont,data);
}
void WSCcomboBox::getWorkWSNfont(WSCuchar*){}
void WSCcomboBox::setWorkWSNitemHeight(WSCuchar data){
  if (_list != NULL){
    _list->setProperty(WSNitemHeight,data);
    _list->setProperty(WSNincrement,data);
    _list->setProperty(WSNscrollHeight,data-1);
  }
}
void WSCcomboBox::getWorkWSNitemHeight(WSCuchar*){}
void WSCcomboBox::setWorkWSNlabelPixmap(short data){
  _if->setPropertyV(WSNlabelPixmap,data);
}
void WSCcomboBox::getWorkWSNlabelPixmap(short*){}
void WSCcomboBox::setWorkWSNblinkPixmap(short no){
  _if->setPropertyV(WSNblinkPixmap,no);
}
void WSCcomboBox::getWorkWSNblinkPixmap(short*){}

WSCcomboBox::~WSCcomboBox(){
  _menu_popdown();
  if (_win != NULL){
    WSGFcleanupStretchAction(_win);
  }
  if (_win != NULL){
    delete _win;
  }
  if (_menu_str != NULL){
    delete _menu_str;
    _menu_str = NULL;
  }
  if (_upname != NULL){
    delete _upname;
    _upname = NULL;
  }
  if (_dwname != NULL){
    delete _dwname;
    _dwname = NULL;
  }
  if (_lname != NULL){
    delete _lname;
    _lname = NULL;
  }
  if (_rname != NULL){
    delete _rname;
    _rname = NULL;
  }

  if (_rtname != NULL){
    delete _rtname;
    _rtname = NULL;
  }
  if (_tbname != NULL){
    delete _tbname;
    _tbname = NULL;
  }
  if (_btbname != NULL){
    delete _btbname;
    _btbname = NULL;
  }

}

long WSCcomboBox::initialize(){
  WSCstring name;
  name = (WSCstring)"cw-btn-" + getInstanceName();
  _btn = new WSCvarrow(this,name);
  _btn->setInternalObject(True);
  _btn->initialize();
  _btn->setPropertyV(WSNarrowDirection,(char)WS_DOWN);
  _btn->setUserData("_CMB",(void*)this);
  WSCprocedure* op = new WSCprocedure("btn proc",WSEV_MOUSE_PRESS);
  op->setInternal(True);
  op->setFunction(_btn_work,"_btn_work");
  _btn->addProcedure(op);

  name = (WSCstring)"cw-if-" + getInstanceName();
  _if = new WSCvifield(this,name);
  _if->setInternalObject(True);
  _if->initialize();
  _if->setPropertyV(WSNx,(short)0);
  _if->setPropertyV(WSNy,(short)0);
  _if->setPropertyV(WSNshadowType,(char)_shadow_type);
  _if->setProperty(WSNenableFocusMove,True);
  _if->setUserData("_CMB",(void*)this);
  WSCprocedure* op2 = new WSCprocedure("key press proc",WSEV_KEY_PRESS);
  op2->setInternal(True);
  op2->setFunction(_key_press_work,"_key_press_work");
  _if->addProcedure(op2);
  WSCprocedure* op3 = new WSCprocedure("key release proc",WSEV_KEY_RELEASE);
  op3->setInternal(True);
  op3->setFunction(_key_release_work,"_key_release_work");
  _if->addProcedure(op3);
  WSCprocedure* op4 = new WSCprocedure("key release proc",WSEV_KEY_HOOK);
  op4->setInternal(True);
  op4->setFunction(_key_hook_work,"_key_hook_work");
  _if->addProcedure(op4);
  WSCprocedure* op5 = new WSCprocedure("value ch proc",WSEV_VALUE_CH);
  op5->setInternal(True);
  op5->setFunction(_value_ch_work,"_value_ch_work");
  _if->addProcedure(op5);


  _adjust();

  _btn->setVisible(True);
  _if->setVisible(True);

  return WSCform::initialize();
}

void WSCcomboBox::setWorkWSNwidth(WSCushort data){
  WSCform::setWorkWSNwidth(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNheight(WSCushort data){
  WSCform::setWorkWSNheight(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNshadowType(char data){
  WSCform::setWorkWSNshadowType(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNshadowThickness(WSCuchar data){
  WSCform::setWorkWSNshadowThickness(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNforeColor(short data){
  WSCform::setWorkWSNforeColor(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNbackColor(short data){
  WSCform::setWorkWSNbackColor(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNtopShadowColor(short data){
  WSCform::setWorkWSNtopShadowColor(data);
  _adjust();  
}
void WSCcomboBox::setWorkWSNbottomShadowColor(short data){
  WSCform::setWorkWSNbottomShadowColor(data);
  _adjust();  
}

static WSDprivateTimer* _timer = NULL;
long WSCcomboBox::_menu_popup(){
  setUserData("Selected-cleard",(void*)0);
  if (_timer == NULL){
    _timer = WSDprivateTimer::getNewInstance();
    _timer->setRate(20);
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  short px, py;
  dev->getDispAddr(&px,&py);
  py += _h;
  WSCstring str(_menu_str);
  WSCushort height = _max_height;
  char tmp[2];
  tmp[0] = (char)-1;
  tmp[1] = 0;
 
  str.replaceString("\\,",tmp,0);

  long num  = str.getWords(",");
  if (height == 0){
    height = num *_h;
  }
  if (height > WSGIappDev()->getHeight() - py){ 
    height = WSGIappDev()->getHeight() -py;
    if (height < 10){
      height = 10;
    }
  }
  if (_win == NULL){
    WSCstring name;
    name = (WSCstring)"cw-" + getInstanceName();
    _win = new WSCwindow(NULL,name);
    _win->setInternalObject(True);
    _win->initialize();
    name = (WSCstring)"cw-list-" + getInstanceName();
    _list = new WSClist(_win,name);
    _list->setInternalObject(True);
    _list->initialize();
    _list->setPropertyV(WSNhbarVisible,(WSCbool)False);
    _list->setPropertyV(WSNreverseSelect,(WSCbool)False);
    _list->setPropertyV(WSNmargin,(WSCuchar)_shadow_thick);
    _list->setProperty(WSNitemHeight,_item_height);
    _list->setProperty(WSNincrement,_item_height);
    _list->setProperty(WSNscrollHeight,_item_height-1);

    _list->setUserData("_CMB",(void*)this);
    _list->setAbsoluteChangeSelectFlag(True);
    WSCprocedure* op = new WSCprocedure("select proc",WSEV_ACTIVATE);
    op->setFunction(_list_work,"_list_work");
    _list->addProcedure(op);
    WSCprocedure* op2 = new WSCprocedure("click proc",WSEV_MOUSE_PRESS);
    op2->setFunction(_list_ptr_work,"_list_ptr_work");
    _list->addProcedure(op2);

  }
  _win->setPropertyV(WSNforeColor,_fore_color);
  _win->setPropertyV(WSNbackColor,_back_color);
  _win->setPropertyV(WSNtopShadowColor,_ts_color);
  _win->setPropertyV(WSNbottomShadowColor,_bs_color);
  if (WSGIappDev()->getGuiPolicy() & WS_POLICY_ORIGINAL){
    _win->setPropertyV(WSNshadowThickness,(WSCuchar)_shadow_thick);
    _win->setProperty(WSNshadowType,WS_SHADOW_OUT);
  }else
  if (WSGIappDev()->getGuiPolicy() & WS_POLICY_WINDOWS){
    _win->setPropertyV(WSNshadowThickness,(WSCuchar)1);
    _win->setProperty(WSNshadowType,WS_SHADOW_BORDER);
  }
  _win->setPropertyV(WSNx,px);
  _win->setPropertyV(WSNy,py);
  _win->setPropertyV(WSNwidth,_w);
  _win->setPropertyV(WSNheight,height);
  _win->setPropertyV(WSNtitleBar,(char)WS_NO_TITLE);
  _list->setPropertyV(WSNforeColor,_fore_color);
  _list->setPropertyV(WSNbackColor,_back_color);
  _list->setPropertyV(WSNworkBackColor,_work_back_color);
  _list->setPropertyV(WSNtopShadowColor,_ts_color);
  _list->setPropertyV(WSNbottomShadowColor,_bs_color);
  if (WSGIappDev()->getGuiPolicy() & WS_POLICY_ORIGINAL){
    _list->setPropertyV(WSNx,(short)(_shadow_thick + WS_CM_BORDER));
    _list->setPropertyV(WSNy,(short)(_shadow_thick + WS_CM_BORDER));
    _list->setPropertyV(WSNwidth,(WSCushort)(_w - _shadow_thick*2 - WS_CM_BORDER*2));
    _list->setPropertyV(WSNheight,(WSCushort)(height - _shadow_thick*2 - WS_CM_BORDER*2));
    _list->setPropertyV(WSNshadowThickness,(WSCuchar)_shadow_thick);
  }else
  if (WSGIappDev()->getGuiPolicy() & WS_POLICY_WINDOWS){
    _list->setPropertyV(WSNx,(short)(_shadow_thick));
    _list->setPropertyV(WSNy,(short)(_shadow_thick));
    _list->setPropertyV(WSNwidth,(WSCushort)(_w - _shadow_thick*2));
    _list->setPropertyV(WSNheight,(WSCushort)(height - _shadow_thick*2));
    _list->setPropertyV(WSNshadowThickness,(WSCuchar)0);
  }

  _list->setPropertyV(WSNpixmapStyle,(WSCuchar)WS_DYNAMIC_PIXMAP);
  _list->delAll();
  _list->setSelectItemChanged(False);
  _list->setProperty(WSNvbarValue,0);

  long i;
  for(i=0; i<num; i++){
    WSCstring item = str.getWord(i,",");
    item.replaceString(tmp,",",0);
    _list->addItem(item,-1);
  }

  WSDdev* wdev = _win->attachdev();
  if (wdev != NULL){
    WSCbool val = True;
    wdev->setValue(WSDEV_NO_FRAME,(void*)&val);
    wdev->setValue(WSDEV_FLOAT_ON_TOP,(void*)&val);
  }
  _list->setVisible(True);
  if (height < WS_STRETCH_HEIGHT){
    _win->setVisible(True);
  }else{
    WSGFstretchPopup(_win);
  }
  WSDdev* ldev = _list->getowndev();
  if (ldev != NULL){
    WSCbool val = True;
    ldev->setValue(WSDEV_GRAB_POINTER,(void*)&val);
  }
  if (_timer != NULL){
    _timer->setWorkProc(_list_timer_work,this);
    _timer->startTimer();
  }
  return WS_NO_ERR;
}
void WSCcomboBox::_adjust(){
  if (_w - _h > 0){
    _if->setPropertyV(WSNwidth,(WSCushort)(_w - _h));
    _btn->setPropertyV(WSNx,(short)(_w - _h + _shadow_thick +1));
    _btn->setPropertyV(WSNy,(short)(_shadow_thick + 1));
  }else{
    _if->setPropertyV(WSNwidth,(WSCushort)1);
    _btn->setPropertyV(WSNx,(short)(_shadow_thick +1));
    _btn->setPropertyV(WSNy,(short)(_shadow_thick +1));
  }
  _if->setPropertyV(WSNheight,(WSCushort)_h);
  _if->setPropertyV(WSNshadowThickness,(WSCuchar)_shadow_thick);
  _if->setPropertyV(WSNshadowType,(char)_shadow_type);
  _if->setPropertyV(WSNbackColor,(short)_work_back_color);
  _if->setPropertyV(WSNforeColor,(short)_fore_color);
  _if->setPropertyV(WSNtopShadowColor,(short)_ts_color);
  _if->setPropertyV(WSNbottomShadowColor,(short)_bs_color);
  _btn->setPropertyV(WSNwidth,(WSCushort)(_h - _shadow_thick *2 -2));
  _btn->setPropertyV(WSNheight,(WSCushort)(_h - _shadow_thick *2 -2));
  _btn->setPropertyV(WSNshadowThickness,(WSCuchar)_shadow_thick);
  _btn->setPropertyV(WSNbackColor,(short)_back_color);
  _btn->setPropertyV(WSNforeColor,(short)_fore_color);
  _btn->setPropertyV(WSNtopShadowColor,(short)_ts_color);
  _btn->setPropertyV(WSNbottomShadowColor,(short)_bs_color);
}
long WSCcomboBox::_menu_popdown(){
  if (_win != NULL){
    WSCushort height;
    _win->getPropertyV(WSNheight,&height);
    if (height < WS_STRETCH_HEIGHT){
      _win->setVisible(False);
    }else{
      WSGFstretchPopdown(_win);
    }
  }
  if (_timer != NULL){
    _timer->stopTimer();
  }
  long fl = (long)getUserData("Selected-cleard");
  if (fl != False){
    setFocus(True);
    return WS_NO_ERR;
  }
  if (_list == NULL){
    setFocus(True);
    return WS_NO_ERR;
  }
  if (_list->getSelectedPos() > -1){
    WSCstring data;
    data = _list->getSelectedItem();
    _if->setPropertyV(WSNlabelString,(char*)data);
    onActivate();
  }
  setFocus(True);
  return WS_NO_ERR;
}
long WSCcomboBox::_device_initialize(){
  WSCform::_device_initialize();
  return WS_NO_ERR;
}
void WSCcomboBox::onActivate(){
//  execEventProc(WSEV_ACTIVATE,NULL);
  execProcedure(WSEV_ACTIVATE);
}
long WSCcomboBox::draw(){
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  WSCbool absolute = getAbsoluteDraw();
  if (absolute == False  ){
    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{
      if ( dev->isExposed(0,0,_w,_h) == False ){
        return WS_NO_ERR;
      }
    }
  }
  if (_shadow_thick > 0 || getDotMode() != False){
    long err = dev->beginDraw(0,0,_w,_h,absolute);
    if (err != WS_NO_ERR){
      return WS_NO_ERR;
    }
    short ex = _w - _h;
    if (ex < 0){
      ex = 0;
    }
    short ey = 0;
    WSCushort ew = _h;
    WSCushort eh = _h;
    WSCbase::update();
    setAbsoluteDraw(False);
    WSGFdrawShadow(dev,_shadow_type,_shadow_thick,_fore_color,_ts_color,_bs_color,_back_color,ex,ey,ew,eh);
    dev->endDraw();
  }
  return WS_NO_ERR;
}

void WSCcomboBox::_list_timer_work(void* ptr){
  WSCcomboBox* cmb = (WSCcomboBox*)ptr;
  WSClistData* lbs = cmb->_list->getLabels();
  long i;
  long num = lbs->getNum();
  WSCushort vx,vy;
  cmb->_list->getPropertyV(WSNhbarValue,&vx);
  cmb->_list->getPropertyV(WSNvbarValue,&vy);
//printf("void WSCcomboBox::_list_timer_work(void* ptr)\n");
  for(i=0; i<num; i++){
    WSCbase* lb = (WSCbase*)(*lbs)[i];
    short px,py;
    WSGIappMouse()->getMousePosition(&px,&py,lb);
    WSCushort sw,sh;
    WSCbase* scrframe = cmb->_list->getdev()->getAttachedClient();
    scrframe->getPropertyV(WSNwidth,&sw);
    lb->getPropertyV(WSNheight,&sh);
//    px += vx;
//    py += vy;
    if (0 < px && px < sw && 
        0 < py && py < sh ){
      cmb->_list->setEnableActivate(False);
      cmb->_list->setSelectPos(i);
      cmb->_list->setSelectItemChanged(False);
      cmb->_list->setEnableActivate(True);
      cmb->_list->cdraw();
      break;
    }
  }
}

void WSCcomboBox::_list_ptr_work(WSCbase* list){
  WSCcomboBox* cmb = (WSCcomboBox*)list->getUserData("_CMB");
//printf("WSCcomboBox::_list_ptr_work cmb=0x%x\n",cmb);
  if (cmb == NULL){
    return;
  }
  short px,py;
  WSGIappMouse()->getMousePosition(&px,&py,list);
//  short sx=0,sy=0;
  WSCushort sw=0,sh=0;
  list->getPropertyV(WSNwidth,&sw);
  list->getPropertyV(WSNheight,&sh);
  long wx = list->getProperty(WSNhbarValue);
  px -= wx;
  long wy = list->getProperty(WSNvbarValue);
  py -= wy;
//printf("WSCcomboBox::_list_ptr_work x,y=%d,%d sw,sh=%d,%d\n",px,py,sw,sh);
  if (px < 0 || sw < px ||
      py < 0 || sh < py ){
    WSDdev* ldev = cmb->_list->getowndev();
    if (ldev != NULL){
      WSCbool val = False;
      ldev->setValue(WSDEV_GRAB_POINTER,(void*)&val);
    }
    cmb->setUserData("Selected-cleard",(void*)1);
    cmb->_menu_popdown();
  }

  WSDdev* ldev = list->getdev();
  if (ldev != NULL){
    WSCbase* scrframe = ldev->getAttachedClient();
    if (scrframe != NULL){
//      scrframe->getPropertyV(WSNx,&sx);
//      scrframe->getPropertyV(WSNy,&sy);
      scrframe->getPropertyV(WSNwidth,&sw);
      scrframe->getPropertyV(WSNheight,&sh);
    }
#if 0
    if (sx < px && px < sx+ sw && sy < py && py < sy+ sh ){
      WSCushort vx,vy;
      scrframe->getPropertyV(WSNhbarValue,&vx);
      scrframe->getPropertyV(WSNvbarValue,&vy);
      WSCpoint pt;
      pt.x = px + vx;
      pt.y = py + vy;
      ldev->execEvent(WSEV_MOUSE_PRESS,&pt);
    }
#endif
    if (0 < px && px < sw && 0 < py && py < sh ){
      long scrpos = list->getProperty(WSNvbarValue);
      WSCpoint pt;
//      pt.x = px - wx;
//      pt.y = py - wy;
      pt.x = px;
      pt.y = py + scrpos;
//printf("WSCcomboBox::_list_ptr_work pt.x,pt.y=%d,%d\n",pt.x,pt.y);
//      ldev->execEvent(WSEV_MOUSE_PRESS,&pt);
      cmb->_list->setSelectItemChanged(True);
      cmb->_list->onActivate();
    }
  }
}

void WSCcomboBox::_list_work(WSCbase* list){
  WSCcomboBox* cmb = (WSCcomboBox*)list->getUserData("_CMB");
  if (cmb == NULL){
    return;
  }
  if (cmb->_list->getSelectItemChanged() != False){
    WSDdev* ldev = cmb->_list->getowndev();
    if (ldev != NULL){
      WSCbool val = False;
      ldev->setValue(WSDEV_GRAB_POINTER,(void*)&val);
    }
    cmb->_menu_popdown();
  }
}
void WSCcomboBox::onFocusChange(WSCbool fl){
  if (_if != NULL){
    _if->setFocus(True);
  }
}
void WSCcomboBox::_value_ch_work(WSCbase* ifield){
  WSCcomboBox* cmb = (WSCcomboBox*)ifield->getUserData("_CMB");
  if (cmb == NULL){
    return;
  }
  cmb->execProcedure(WSEV_VALUE_CH);
}
void WSCcomboBox::_key_press_work(WSCbase* ifield){
  WSCcomboBox* cmb = (WSCcomboBox*)ifield->getUserData("_CMB");
  if (cmb == NULL){
    return;
  }
  cmb->execProcedure(WSEV_KEY_PRESS);
}
void WSCcomboBox::_key_release_work(WSCbase* ifield){
  WSCcomboBox* cmb = (WSCcomboBox*)ifield->getUserData("_CMB");
  if (cmb == NULL){
    return;
  }
  cmb->execProcedure(WSEV_KEY_RELEASE);
}
void WSCcomboBox::_key_hook_work(WSCbase* ifield){
  WSCcomboBox* cmb = (WSCcomboBox*)ifield->getUserData("_CMB");
  if (cmb == NULL){
    return;
  }
  cmb->execProcedure(WSEV_KEY_HOOK);
}
void WSCcomboBox::_btn_work(WSCbase* btn){
  WSCcomboBox* cmb = (WSCcomboBox*)btn->getUserData("_CMB");
  if (cmb == NULL){
    return;
  }
  if (cmb->_win == NULL || cmb->_win->getVisible() == False){
    cmb->_menu_popup();
  }else{
    cmb->_menu_popdown();
  }
  short x,y;
  WSGIappMouse()->getMousePosition(&x,&y,btn);
  WSCpoint pt;
  pt.x = x;
  pt.y = y;
  btn->execEventProc(WSEV_MOUSE_RELEASE,(void*)&pt);
}
char* WSCcomboBox::getDefaultProperty(){
  return WSNlabelString;
}
