//
// 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 <WSCconductor.h>
#include <WSDserialize.h>
#include <WSCprocedure.h>
#include <WSCbase.h>

static void _base_save(WSDserialize* db,void* ptr){
  WSCbase* obj = (WSCbase*)ptr;
  if (obj->getInternalObject() == False){
    WSClistData prop_strings;
    long i;
    long num;

    db->saveData(WS_DcRString,">name",obj->getInstanceName());
    obj->getPropertyArray(&prop_strings,False);
    num = prop_strings.getNum();
    long slen = 0;
    for(i=0; i< num; i++){
        slen += strlen( (char*)prop_strings.getData(i) ) +1;
    }
    char* vals = new char[slen +32];
    vals[0] =0;
    long ptr = 0;
    char* vstr;
    long vlen;
    for(i=0; i< num; i++){
      vstr = (char*)prop_strings.getData(i);
      vlen = strlen(vstr);
      memcpy(&vals[ptr], vstr, vlen );
      delete vstr;
      ptr += vlen;
      vals[ptr] = (char)-1;
      ptr ++;
    }
    vals[ptr-1] = 0;
    db->saveData(WS_DcRString,">props",vals);
    delete vals;

    WSClistData* prclist = obj->getProcedureList();
    num = prclist->getNum();
    WSCstring tmp;
    if (num != 0){
      for(i=0; i< num; i++){
        WSCprocedure* ac = (WSCprocedure*)prclist->getData(i);
        if (ac->getInternal() != False){
          continue;
        }
        tmp = WSGFltoa(ac->getTrigger());
        tmp << " " << ac->getFunctionName()
            << " " << ac->getProcName();
      }
      db->saveData(WS_DcRString,">ops",(char*)tmp);
    }
    obj->onDataSave(db);
  }

  WSClistData children = obj->getChildren();
  long cnum = children.getNum();
  long i;
  for(i=0; i < cnum; i++){
    WSCbase* child = (WSCbase*)children.getData(i);
    if (child->getInternalObject() == False){
      db->saveData(child->getClassName(),child->getInstanceName(),child);
    }
  }
}

static void _base_load(WSDserialize* db,void* ptr){
  WSCbase* obj = (WSCbase*)ptr;
  char* objname = NULL;
  db->loadAllocData(WS_DcRString,">name",(void**)&objname,NULL);
  if (objname != NULL){
    obj->setInstanceName(objname);
    delete objname;
  }

  char* val = NULL;
  db->loadAllocData(WS_DcRString,">props",(void**)&val,NULL);

  if (val != NULL){
    register long start = 0;
    register long end = 0;
    register long start2 = 0;
    register long end2 = 0;
    while(1){
      while( val[end] != 0 && val[end] != (char)-1 ){
        end++;
      }
      val[end] = 0;

      start2 = end +1;
      end2 = end +1;
      while( val[end2] != 0 && val[end2] != (char)-1 ){
        end2++;
      }


      if (val[end2] == 0){
        obj->setProperty( &val[start],&val[start2] );
        break;
      }
      val[end2] = 0;
      obj->setProperty( &val[start],&val[start2] );
      start = end2 +1;
      end   = end2 +1;
      start2 = end2 +1;
      end2   = end2 +1;
    }
  }
  delete val;

  char* ops = NULL;
  db->loadAllocData(WS_DcRString,">ops",(void**)&ops,NULL);
  if (ops != NULL){
    WSCstring tmp;
    tmp.setString(ops);
    delete ops;
    while(!tmp.eof()){
      WSCstring str = tmp.gets();
      WSCstring trgn = str.getWord(0);
      long trg = atoi((char*)trgn);
      WSCstring fname = str.getWord(1);
      WSCstring iname = str.getWord(2);
//      if (tmp.eof()){
//        break;
//      }
//      str = tmp.gets();
//printf("iname=%s fname=%s %d\n",(char*)iname,(char*)fname,trg);
      WSCprocedure* ac = new WSCprocedure((char*)iname,trg);
      ac->setFunction(NULL,(char*)fname);
      obj->addProcedure(ac);
    }
  }

  obj->onDataLoad(db);

  char** cname;
  char** data;
  long   num;
  db->searchInstanceData("WSCbase",WS_SEARCH_INHERIT,&cname,&data,&num);
  if (num != 0){
    for(int i = 0; i < num; i++){
      WSCbase* base;
      db->loadAllocData("WSCbase",data[i],(void**)&base,obj); 
    }
    delete cname;
    delete data;
  }
}

static void* _base_create(void* ptr){
   WSCbase* parent = (WSCbase*)ptr; 
   WSCbase* ret =  new WSCbase(parent,"");
   return ret;
}
static void _base_delete(void* ptr){
   WSCbase* base = (WSCbase*)ptr; 
   delete base;
}

WSMFdefineDrClient  (WSCbase, _base_save, _base_load, _base_create,_base_delete);


