//
// 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 <advance/WSCobjectBox.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSDdev.h>
#include <WSCscrForm.h>
#include <WSCvlabel.h>
#include <WSCvtoggle.h>
#include <WSCvifield.h>
#include <WSCvbtn.h>
#include <WSDkeyboard.h>
#include <WSCimageSet.h>
#include <WSDfileSystem.h>
#include <WSDfile.h>
#include <WSCvlabel.h>
#include <WSDdragDrop.h>
#include <WSCballoonHelp.h>
#include <WSCindexForm.h>
#include <WSDappDev.h>
#include <WSClocaleSet.h>

#define WS_TOOLB_PIX    WS_PIXMAP_DIR "bi24.xpm"

#define WS_TB_WIDTH     450
#define WS_TB_HEIGHT    280
#define WS_TB_SCRHEIGHT 600
//#define WS_TB_BGCOLOR1  "gray85"
//#define WS_TB_BGCOLOR2  "gray80"
//#define WS_TB_SLBARBG1  "gray80"
//#define WS_TB_SELECTBG  "slategray2"
#define WS_TB_T         48
#define WS_TB_H         48
#define WS_TB_W         48
#define WS_TB_X         8
#define WS_TB_Y         8

WSMFguiClassInitialize(WSCobjectBox,WSCbaseDialog);

WSCobjectBox::WSCobjectBox(WSCbase* base,char* objname):
                WSCbaseDialog(base,objname){

    _set_btn = NULL;
    _class_text = NULL;
    _visible_lbs = 0;
    _form = NULL;
	_file_name = WSGFstrdup("");
    _no = False;
    _index = NULL;

  WSMFpropertyCreateStart
    WSMFpropertyCreate(WSNfileName,char*,_file_name,WSSfileName);
  WSMFpropertyCreateEnd
}

WSMFproperty( WSCobjectBox, WSNfileName, char*, _file_name, WSGFstrdup(""));

void WSCobjectBox::setWorkWSNfileName(char* /*data*/){
  updateList();
}

void WSCobjectBox::getWorkWSNfileName(char** /*data*/){
}

void WSCobjectBox::clearItems(){
  long num = _added.getNum();
  long i;
  for(i=0; i<num; i++){
    WSCstring* items = (WSCstring*)_added[i];
    delete items;
  }
  _added.clear();
  updateList();
}
void WSCobjectBox::addItems(WSCstring* str){
  WSCstring* items = new WSCstring;
  items->setString(str->getString());
  _added.add((void*)items);
  updateList();
}

void WSCobjectBox::delItems(WSCstring* str){
  long num = _added.getNum();
  long i;
  for(i=0; i<num; i++){
    WSCstring* items = (WSCstring*)_added.getData(i);
    if (!strcmp(items->getString(),str->getString())){
      _added.del((void*)items);
      delete items;
    }
  }
  updateList();
}

void WSCobjectBox::updateList(){
  _req_lib_by_obj.clear();

  if (!strcmp(_file_name,"")){
    return ;
  }

  _index->setProperty(WSNmenuItems,"");
  WSCstring menu;
  WSCstring files(_file_name);
  long i;
  long num = files.getWords(",");
  long libno = 0;
  for(i=0; i<num+1; i++){
    WSCstring* data = NULL;
    if (i < num){
      WSCstring filename = files.getWord(i,",");
      data = WSGFreadTextFile(filename,
                   WSGIappLocaleSet()->getSystemLocaleEncoding());
      if (data == NULL){
        fprintf(stderr,"Error: Class library definition file can not open. file=%s\n",
                (char*)filename);
        continue;
      }
    }else{
      data = new WSCstring;
      (*data) << "Imported\n";
      long j;
      long n = _added.getNum();
      for(j=0; j < n; j++){
        WSCstring* items = (WSCstring*)_added[j];
//printf("WSCobjectBox::updateList %d=#%s#\n",j,(char*)(*items));

        while(items->eof() == False){
          (*data) << items->gets() << "\n";
          (*data) << items->gets() << "\n";
        }
        items->seek(0);
      }
//printf("WSCobjectBox::updateList added=#%s# num=%d\n",(char*)(*data),n);
    }

    WSCscrForm* scrarea = (WSCscrForm*)_areas[i];

    if (scrarea == NULL){
      scrarea = new WSCscrForm(_index,"fs-area2");
      scrarea->initialize();
      scrarea->setInternalObject(True);
      WSGFsetGeometry(scrarea,5,30,400,150);
      scrarea->setPropertyV(WSNworkWidth,(WSCushort)( WS_TB_X*2 + WS_TB_W * 8));
      scrarea->setPropertyV(WSNworkHeight,(WSCushort)(WS_TB_SCRHEIGHT));
      scrarea->setPropertyV(WSNshadowThickness,(WSCuchar)1);
      scrarea->setPropertyV(WSNshadowType,(char)WS_SHADOW_IN);
//      scrarea->setPropertyV(WSNworkBackColor,(short)WSGFcolor(WS_TB_BGCOLOR1));
//      scrarea->setPropertyV(WSNbarShadowColor,(short)WSGFcolor(WS_TB_SLBARBG1));
      scrarea->setPropertyV(WSNforeColor,WSGFcolor("black"));
//      scrarea->setPropertyV(WSNbackColor,WSGFcolor(WS_TB_BGCOLOR2));
      scrarea->setProperty(WSNbackColor,WS_DF_DARKBACKCOLOR);
//      scrarea->setPropertyV(WSNtopShadowColor,WSGFcolor("gray95"));
//      scrarea->setPropertyV(WSNbottomShadowColor,WSGFcolor("gray35"));
      scrarea->setPropertyV(WSNpixmapStyle,(WSCuchar)WS_DYNAMIC_PIXMAP);
      scrarea->setPropertyV(WSNscrollHeight,(WSCushort)2);
      scrarea->setPropertyV(WSNincrement,(WSCushort)50);
      scrarea->setPropertyV(WSNpageIncrement,(WSCushort)100);
      scrarea->setPropertyV(WSNuserValue,(long)(i+1));
      scrarea->setVisible(True);
      _areas.add(scrarea);
      scrarea->setUserData("lb-list",(void*)(new WSClistData));
    }
    if (WSGIappDev()->getGuiPolicy() & WS_POLICY_ORIGINAL){
      scrarea->setProperty(WSNshadowThickness,1);
    }else
    if (WSGIappDev()->getGuiPolicy() & WS_POLICY_WINDOWS){
      scrarea->setProperty(WSNshadowThickness,2);
    }

    WSCstring comment = data->gets();
    comment.delHeadSpace();
    comment.delTailSpace();
    if (!strcmp((char*)comment,"")){
      libno++;
      menu << "LIB" << WSGFltoa(libno);
    }else{
      menu << comment;
    }
    if (i < num){
      menu << ",";
    }

    WSClistData* lblist = (WSClistData*)scrarea->getUserData("lb-list");
    long j;
    long num2 = lblist->getNum();
    for(j=0; j<num2; j++){
      WSCbase* lb = (WSCbase*)(*lblist)[j];
      lb->setVisible(False);
    }
    long cnt= 0; 
    while( data->eof() == False ){
      WSCstring str = data->gets();

      WSCbase* lb = (WSCbase*)(*lblist)[cnt];
      if (lb == NULL){
        lb = new WSCvlabel(scrarea,"TBlb");
        lb->initialize();
        lb->setInternalObject(True);
        lb->setPropertyV(WSNx,(short)( WS_TB_X + WS_TB_W *(cnt%8)));
        lb->setPropertyV(WSNy,(short)( WS_TB_Y + WS_TB_H *(cnt/8)));
        lb->setPropertyV(WSNwidth,(WSCushort) WS_TB_W );
        lb->setPropertyV(WSNheight,(WSCushort)WS_TB_H );
        lb->setPropertyV(WSNshadowType,(char)WS_SHADOW_OUT);
        lb->setPropertyV(WSNshadowThickness,(WSCuchar)1);
        lb->setUserData("TOOL BOX",(void*)this);
        WSGFsetMargin(lb,0);
        lblist->add(lb);
        WSGIappDragDrop()->registerDragSite(lb,"OBJECT-CREATE");
        WSCprocedure* inop = new WSCprocedure("in op",WSEV_MOUSE_IN);
        inop->setFunction(_label_in_work,"_label_in_work");
        lb->addProcedure(inop);

        WSCprocedure* outop = new WSCprocedure("out op",WSEV_MOUSE_OUT);
        outop->setFunction(_label_out_work,"_label_out_work");
        lb->addProcedure(outop);
//        lb->setPropertyV(WSNtopShadowColor,"gray95");
//        lb->setPropertyV(WSNbottomShadowColor,"gray45");
      }
      lb->setPropertyV(WSNuserString,(char*)str.getWord(0));
      lb->setPropertyV(WSNlabelPixmap,(char*)str.getWord(1));
      lb->setVisible(True);
      WSCstring reqlib = str.getWord(2);
      if (strcmp((char*)reqlib,"")){
        WSCvariant val = (char*)reqlib;
        _req_lib_by_obj.setData((char*)str.getWord(0),val);
      }
      str = data->gets();
      str.delLineFeed();
      WSGIappBalloonHelp()->unregisterClient(lb);
      WSGIappBalloonHelp()->registerClient(lb,str.getString());
      cnt++;
    }
    delete data;
  }
//printf("WSCobjectBox:: _index menu=%s\n",(char*)menu);
  _index->setProperty(WSNmenuItems,(char*)menu);
  _adjust();
  _index->cdraw();
}
WSCstring WSCobjectBox::getRequiredLibrary(char* classname){
  WSCstring ret;
  WSCbool exist = _req_lib_by_obj.isExist(classname);
  if (exist == False){
    return ret;
  }
  ret = _req_lib_by_obj.getData(classname);
  return ret;
}


WSCobjectBox::~WSCobjectBox(){
  long num = _added.getNum();
  long i;
  for(i=0; i<num; i++){
    WSCstring* str = (WSCstring*)_added.getData(i);
    delete str;
  }
  num = _areas.getNum();
  for(i=0; i<num; i++){
    WSCscrForm* scr = (WSCscrForm*)_areas[i];
    WSClistData* lblist =(WSClistData*)scr->getUserData("lb-list");
    long j;
    long num2 = lblist->getNum();
    for(j=0; j<num2; j++){
      WSCvlabel* lb = (WSCvlabel*)(*lblist)[i];
      WSGIappDragDrop()->unregisterDragSite(lb);
    }
    delete lblist;
  }
  delete _file_name;
}


void WSCobjectBox::_label_in_work(WSCbase* obj){
  WSCobjectBox* fs = (WSCobjectBox*)obj->getUserData("TOOL BOX");
  WSCstring str(obj->getProperty(WSNuserString));
  if (strcmp(str,"")){
//WSMFtrace("WSCobjectBox::_label_in_work   %s\n",str);
    fs->_class_text->setPropertyV(WSNlabelString,(char*)str);
    fs->_class_text->redraw();
//    obj->setPropertyV(WSNtopShadowColor,"cyan2");
//    obj->setPropertyV(WSNbottomShadowColor,"cyan4");
    obj->update();
  }
}

void WSCobjectBox::_label_out_work(WSCbase* obj){
  WSCobjectBox* fs = (WSCobjectBox*)obj->getUserData("TOOL BOX");


  //もし同じだったら消す なぜかというと、他の人がすでに変更している
  //場合があり、消す必要がないときがあるからである。
//  if ( fs->_class_text->cmpPropertye(WSNlabelString, obj->getProperty(WSNuserString) ) ){
  if ( !strcmp(fs->_class_text->getProperty(WSNlabelString),obj->getProperty(WSNuserString) ) ){
    fs->_class_text->setPropertyV(WSNlabelString,"");
    fs->_class_text->update();
  }
//  obj->setPropertyV(WSNtopShadowColor,"gray95");
//  obj->setPropertyV(WSNbottomShadowColor,"gray45");
  obj->update();

}

void WSCobjectBox::_set_btn_work(WSCbase* obj){
  WSCobjectBox* fs = (WSCobjectBox*)obj->getUserData("TOOL BOX");
  fs->setVisible(False);
}

long WSCobjectBox::initialize(){
  WSCbaseDialog::initialize();
  setPropertyV(WSNwidth,(WSCushort)WS_TB_WIDTH);
  setPropertyV(WSNheight,(WSCushort)WS_TB_HEIGHT);
  setPropertyV(WSNtitleString,"ObjectBox");
  setProperty(WSNok,False);

  _form = new WSCform(this,"tb-area");
  _form->initialize();
  _form->setInternalObject(True);
  _form->setPropertyV(WSNx,(short)1);
  _form->setPropertyV(WSNy,(short)5);
  _form->setPropertyV(WSNwidth, (WSCushort)(WS_TB_WIDTH -10));
  _form->setPropertyV(WSNheight,(WSCushort)(WS_TB_HEIGHT -45));
//  _form->setPropertyV(WSNbackColor,"gray80");
  _form->setProperty(WSNbackColor,WS_DF_DARKBACKCOLOR);
//  _form->setPropertyV(WSNtopShadowColor,"gray95");
//  _form->setPropertyV(WSNbottomShadowColor,"gray45");
  _form->setVisible(True);

  _class_text = new WSCvlabel(_form,"fs-dtitle");
  _class_text->initialize();
  _class_text->setInternalObject(True);
  _class_text->setPropertyV(WSNx,     (short)55 );
  _class_text->setPropertyV(WSNy,     (short)7 );
  _class_text->setPropertyV(WSNwidth, (WSCushort)(WS_TB_WIDTH - 70));
  _class_text->setPropertyV(WSNheight,(WSCushort)16);
  _class_text->setPropertyV(WSNlabelString,"");
  _class_text->setPropertyV(WSNforeColor,"cyan4");
  _class_text->setPropertyV(WSNalignmentH,(WSCuchar)WS_LEFT);
  _class_text->setPropertyV(WSNshadowType,(char)WS_SHADOW_TRANS);
  _class_text->setVisible(True);
  WSGFsetMargin(_class_text,0);

  WSCvlabel* sp1 = new WSCvlabel(_form,"FS-sp1");
  sp1->initialize();
  sp1->setInternalObject(True);
  WSGFsetGeometry(sp1,0,30,1280,2);
  sp1->setPropertyV(WSNshadowThickness,(WSCuchar)1);
  sp1->setPropertyV(WSNshadowType,(char)WS_SHADOW_IN);
//  sp1->setPropertyV(WSNbackColor,"gray80");
  sp1->setProperty(WSNbackColor,WS_DF_BACKCOLOR);
  sp1->setProperty(WSNtopShadowColor,WS_DF_TOPSHADOWCOLOR);
  sp1->setProperty(WSNbottomShadowColor,WS_DF_BOTTOMSHADOWCOLOR);
  sp1->setVisible(True);

  WSCbase* dtitle = new WSCvlabel(_form,"fs-dtitle");
  dtitle->initialize();
  dtitle->setInternalObject(True);
  dtitle->setPropertyV(WSNx,     (short)5 );
  dtitle->setPropertyV(WSNy,     (short)7 );
  dtitle->setPropertyV(WSNwidth, (WSCushort)45);
  dtitle->setPropertyV(WSNheight,(WSCushort)16);
  dtitle->setPropertyV(WSNlabelString,"CLASS:");
  dtitle->setPropertyV(WSNalignmentH,(WSCuchar)WS_LEFT);
  dtitle->setPropertyV(WSNshadowType,(char)WS_SHADOW_TRANS);
  dtitle->setVisible(True);
  WSGFsetMargin(dtitle,0);

  _index = new WSCindexForm(_form,"ob-area");
  _index->initialize();
  _index->setInternalObject(True);
  WSGFsetGeometry(_index,5,38,400,200);
//  _index->setPropertyV(WSNtopShadowColor,WSGFcolor("gray95"));
//  _index->setPropertyV(WSNbackColor,WSGFcolor("gray80"));
  _index->setProperty(WSNbackColor,WS_DF_DARKBACKCOLOR);
//  _index->setPropertyV(WSNbottomShadowColor,WSGFcolor("gray55"));
  _index->setPropertyV(WSNshadowThickness,(WSCuchar)1);
  _index->setPropertyV(WSNmenuItems,"");
  _index->setVisible(True);
  _index->setUserData("inspector",this);

  onGuiPolicyChange(WSGIappDev()->getGuiPolicy());

  setPropertyV(WSNfileName,"");
  return WS_NO_ERR;
}
void WSCobjectBox::onResize(WSCrect* rect){
  WSCbaseDialog::onResize(rect);
  _adjust();
}

void WSCobjectBox::_adjust(){
  long diff = 0;
  if (WSGIappDev()->getGuiPolicy() & WS_POLICY_ORIGINAL){
    diff = 0;
  }else
  if (WSGIappDev()->getGuiPolicy() & WS_POLICY_WINDOWS){
    diff = 45;
  }
  if (_w > 2){
    _form->setPropertyV(WSNwidth,(WSCushort)(_w -2));
  }else{
    _form->setPropertyV(WSNwidth,(WSCushort)(1));
  }
  if (_h+diff > 45  ){
    _form->setPropertyV(WSNheight,(WSCushort)(_h+diff -45));
  }else{
    _form->setPropertyV(WSNheight,(WSCushort)(1));
  }
  if (_w > 12){
    _index->setPropertyV(WSNwidth,(WSCushort)(_w -12));
  }else{
    _index->setPropertyV(WSNwidth,(WSCushort)(1));
  }
  if (_h+diff > 90 ){
    _index->setPropertyV(WSNheight,(WSCushort)(_h+diff -90));
  }else{
    _index->setPropertyV(WSNheight,(WSCushort)(1));
  }

  long i;
  long num = _areas.getNum();
  for(i=0; i<num; i++){
    WSCbase* scr = (WSCbase*)_areas[i];
    if(_w > 22){
      scr->setPropertyV(WSNwidth,(WSCushort)(_w - 22));
    }else{
      scr->setPropertyV(WSNwidth,(WSCushort)(1));
    }
    if (_h+diff > 125 ){
      scr->setPropertyV(WSNheight,(WSCushort)(_h+diff -125));
    }else{
      scr->setPropertyV(WSNheight,(WSCushort)(1));
    }
  }
}
void WSCobjectBox::onGuiPolicyChange(long policy){
  if (_form != NULL){
    WSCbaseDialog::onGuiPolicyChange(policy);
    if (policy & WS_POLICY_ORIGINAL){
      _form->setProperty(WSNy,5);
      _form->setPropertyV(WSNshadowThickness,(WSCuchar)1);
    }else
    if (policy & WS_POLICY_WINDOWS){
      _form->setProperty(WSNy,0);
      _form->setPropertyV(WSNshadowThickness,(WSCuchar)0);
    }
    updateList();
    _adjust();
  }
}
void WSCobjectBox::resetRequiredLibrary(){
  _req_lib_by_obj.clear();
}
