//
// 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 <WSCproperty.h>
#include <WSCbase.h>

WSCproperty::WSCproperty(char* pname,char* cname){
   property_name = pname;
   owner_class_name = cname;
   _builder_visible = True;
   _get_proc_addr = NULL;
   _set_proc_addr = NULL;
   _def_proc_addr = NULL;
   _not_use = False;
   _init_execute = False;
//   _builder_title ="";
   _data_labels = NULL;
   _data = NULL;
   _is_pixmap = False;
   _is_color = False;
   _ignore = 0;
   _default_value_change = 0;
   _file_select = 0;
}
void WSCproperty::setType(char* type,void(*p1)(void*,void*),
                                      void(*p2)(void*,void*),
                                      void(*gd1)(void*)){
  char buf[256];
  char buf2[256];
  buf[0] = 0;
  buf2[0] = 0;

  _prop_type = WSTulong;
  if (type[0] == 'u' && !strncmp(type,"unsigned",8)){
    sscanf(type,"%s %s",buf,buf2);
    if (buf2[0] == 'c' && !strcmp(buf2,"char")){
      _prop_type = WSTuchar;
    }else if (buf2[0] == 's' && !strcmp(buf2,"short")){
      _prop_type = WSTushort;
    }else if (buf2[0] == 'l' && !strcmp(buf2,"long")){
      _prop_type = WSTulong;
    }else{
      _prop_type = WSTulong;
    }
  }else if (type[0] == 'i' && !strcmp(type,"int")){
      _prop_type = WSTlong;
  }else if (type[0] == 'l' && !strcmp(type,"long")){
      _prop_type = WSTlong;
  }else if (type[0] == 'c' && !strcmp(type,"char")){
    sscanf(type,"%s %s",buf,buf2);
    if (!strcmp(buf2,"*")){
      _prop_type = WSTcharptr;
    }else{
      _prop_type = WSTchar;
    }
  }else if (type[0] == 'c' && !strcmp(type,"char*")){
      _prop_type = WSTcharptr;
  }else if (type[0] == 's' && !strcmp(type,"short")){
      _prop_type = WSTshort;
  }else if (type[0] == 'W'){
    if (!strcmp(type,"WSCbool")){
      _prop_type = WSTbool;
    }else if (!strcmp(type,"WSCuchar")){
      _prop_type = WSTuchar;
    }else if (!strcmp(type,"WSCushort")){
      _prop_type = WSTushort;
    }else if (!strcmp(type,"WSCulong")){
      _prop_type = WSTulong;
    }
  }else if (type[0] == 'd' && !strcmp(type,"double")){
      _prop_type = WSTdouble;
  }else if (type[0] == 'f' && !strcmp(type,"float")){
      _prop_type = WSTfloat;
  }else if (type[0] == 'v' && !strcmp(type,"void")){
    sscanf(type,"%s %s",buf,buf2);
    if (!strcmp(buf2,"*")){
      _prop_type = WSTvoidptr;
    }else{
      _prop_type = WSTvoid;
    }
  }else{
      _prop_type = WSTvoidptr;
  }
  _set_proc_addr = p1;
  _get_proc_addr = p2;
  _def_proc_addr = gd1; 

  if (_prop_type == WSTshort){
    char* pname = property_name;
    long len = strlen(pname);
    if (len > 5){
      if (!strcmp(&pname[len -6],"Pixmap")){
        _is_pixmap = True;
      }else
      if (len < 7){
      }else
      if (!strncmp(&pname[len -7],"Pixmap",6)){
        if ( '0' <= pname[len-1] &&
             '9' >= pname[len-1] ){
          _is_pixmap = True;
        }
      }else
      if (len < 8){
      }else
      if (!strncmp(&pname[len -8],"Pixmap",6)){
        if ( '0' <= pname[len-2] &&
             '9' >= pname[len-2] &&
             '0' <= pname[len-1] &&
             '9' >= pname[len-1] ){
          _is_pixmap = True;
        }
      }
    }
  }
  if (_prop_type == WSTshort){
    char* pname = property_name;
    long len = strlen(pname);
    if (len > 4){
      if (!strcmp(&pname[len -5],"Color")){
        _is_color = True;
      }else
      if (len < 6){
      }else
      if (!strncmp(&pname[len -6],"Color",5)){
        if ( '0' <= pname[len-1] &&
             '9' >= pname[len-1] ){
          _is_color = True;
        }
      }else
      if (len < 7){
      }else
      if (!strncmp(&pname[len -7],"Color",5)){
        if ( '0' <= pname[len-2] &&
             '9' >= pname[len-2] &&
             '0' <= pname[len-1] &&
             '9' >= pname[len-1] ){
          _is_color = True;
        }
      }
    }
  }
}

WSCbool WSCproperty::isPixmapPropObj(){
  return _is_pixmap;
}
WSCbool WSCproperty::isColorPropObj(){
  return _is_color;
}
WSCbool WSCproperty::getNotUse(){
  return _not_use;
}
char* WSCproperty::getPropObjTypeName(){
  switch(_prop_type){
    case WSTchar: return "char";
    case WSTbool: return "WSCbool";
    case WSTuchar: return "unsigned char";
    case WSTshort: return "short";
    case WSTushort: return "unsigned short";
    case WSTlong: return "long";
    case WSTulong: return "unsigned long";
    case WSTfloat: return "float";
    case WSTdouble: return "double";
    case WSTvoidptr: return "void*";
    case WSTcharptr: return "char*";
    case WSTvoid: return "void";
  }
  return "void*";
}
WSCbool WSCproperty::getBuilderVisible(){
   return _builder_visible;
}
WSCbool WSCproperty::getFileSelect(){
   return _file_select;
}
char* WSCproperty::getPropObjName(){
  return property_name;
}
char WSCproperty::getPropObjType(){
   return _prop_type;
}
long WSCproperty::setValue(WSCbase* obj,void* data){
  void* ptr = obj->cast(owner_class_name);
  if (_set_proc_addr == NULL){
    return WS_ERR;
  }else{
    _set_proc_addr(ptr,data);
    return WS_NO_ERR;
  }
}
long WSCproperty::getValue(WSCbase* obj,void* data){
  void* ptr = obj->cast(owner_class_name);
  if (_get_proc_addr == NULL){
    return WS_ERR;
  }else{
    _get_proc_addr(ptr,data);
    return WS_NO_ERR;
  }
}
long WSCproperty::execSetHandler(void* ptr){
  if (_def_proc_addr == NULL){
    return WS_ERR;
  }else{
    if (_set_proc_addr == NULL){
      return WS_ERR;
    }

    void* data;
    _def_proc_addr((void*)&data);
    _set_proc_addr(ptr,(void*)&data);
    return WS_NO_ERR;
  }
}
void WSCproperty::setDefaultValue(WSCbase* obj){
  void* def;
  void* val;
  getDefaultValue((void*)&def);
  if (_prop_type == WSTcharptr){
    getValue(obj,&val);
  }
  setValue(obj,&def);
  if (_prop_type == WSTcharptr){
    delete (char*)val;
  }
}
long WSCproperty::getDefaultValue(void* data){
  if (_def_proc_addr == NULL){
    return WS_ERR;
  }else{
    _def_proc_addr(data);
    return WS_NO_ERR;
  }
}
void WSCproperty::setGetDefaultValueHandler(void (*hd)(void*)){
  _def_proc_addr = hd;
}
void* WSCproperty::getGetDefaultValueHandler(){
  return (void*)_def_proc_addr;
}
WSCbool WSCproperty::isDefaultValue(WSCbase* obj){
  char dval[16];
  char val[16];

  getDefaultValue((void*)dval);
  getValue(obj,(void*)val);
  if (_prop_type == WSTcharptr){
    if (*(char**)val == NULL){
      *(char**)val = "";
    }
    if (*(char**)dval == NULL){
      *(char**)dval = WSGFstrdup("");
    }
    if (!strcmp(*(char**)val,*(char**)dval)){
      delete *(char**)dval;
      return True;
    }else{
      delete *(char**)dval;
      return False;
    }
  }else{
    switch(_prop_type){
      case WSTshort:
        if (*(short*)dval == *(short*)val){
          return True;
        }
        return False;
      case WSTushort:
        if (*(WSCushort*)dval == *(WSCushort*)val){
          return True;
        }
        return False;
      case WSTchar:
      case WSTbool:
        if (*(char*)dval == *(char*)val){
          return True;
        }
        return False;
      case WSTuchar:
        if (*(WSCuchar*)dval == *(WSCuchar*)val){
          return True;
        }
        return False;
      case WSTlong:
        if (*(long*)dval == *(long*)val){
          return True;
        }
        return False;
      case WSTulong:
        if (*(WSCulong*)dval == *(WSCulong*)val){
          return True;
        }
        return False;
      case WSTvoidptr:
        if (*(void**)dval == *(void**)val){
          return True;
        }
        return False;
      case WSTfloat:
        if (*(float*)dval == *(float*)val){
          return True;
        }
        return False;
      case WSTdouble:
        if (*(double*)dval == *(double*)val){
          return True;
        }
    }
    return False;
  }
}
char* WSCproperty::getBuilderTitle(){
  return (char*)_builder_title;
}
WSCbool WSCproperty::getDefaultValueChange(){
  return _default_value_change;
}
void WSCproperty::setBuilderSelectValues(char* labels[],char* data[]){
   _data_labels = labels;
   _data = data;
}
void WSCproperty::getBuilderSelectValues(char*** labels,char*** data){
  *labels = (char**)_data_labels;
  *data = (char**)_data;
}
