//
// 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 <WSCcolorSet.h>
#include <WSDfileSystem.h>
#include <WSDfile.h>

static WSCcolorSet* _the_app_color_list = NULL;

WSCcolorSet* WSGIappColorSet(){
  if (_the_app_color_list == NULL){
    _the_app_color_list = new WSCcolorSet();
  }
  return _the_app_color_list;
};
WSCcolorSet::WSCcolorSet(){
  _color_create_handler = NULL;

  long i;
  for(i=0; i<WS_MAX_DF_COLORS;i++){
    _default_cols[i] =1;
    _default_colors[i] =NULL;
  }
#if 0
  _default_fg = 1;
  _default_fg_color = NULL;
  _default_bg = 1;
  _default_bg_color = NULL;
  _default_ts = 1;
  _default_ts_color = NULL;
  _default_bs = 1;
  _default_bs_color = NULL;
  _default_mfg = 1;
  _default_mfg_color = NULL;
  _default_mbg = 1;
  _default_mbg_color = NULL;
  _default_msc = 1;
  _default_msc_color = NULL;
  _default_mts = 1;
  _default_mts_color = NULL;
  _default_mbs = 1;
  _default_mbs_color = NULL;
  _default_dbg = 1;
  _default_dbg_color = NULL;
  _default_wbg = 1;
  _default_wbg_color = NULL;
  _default_bsc = 1;
  _default_bsc_color = NULL;
#endif
  _local_cno = MAX_COLOR_ID;
  memset(_cache_table,0,WS_MAX_HASH_VALUE*sizeof(WSDcolor*));
  memset(_cache_table2,0,WS_MAX_HASH_VALUE*sizeof(WSDcolor*));
}
WSCcolorSet::~WSCcolorSet(){
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    delete col;
  }
}
WSDcolor* WSCcolorSet::getNewColor(){
  if (_color_create_handler != NULL){
    return _color_create_handler();
  }
  return NULL;
}
WSDcolor* WSCcolorSet::getColor(short no){
  if (no < 0){
    return getDefaultColor(no);
  }
  long hval = no % WS_MAX_HASH_VALUE;
  if (_cache_table2[hval] != NULL){
    short id = _cache_table2[hval]->getId();
    if (id == no){
      return _cache_table2[hval];
    }
  }
  long i;
  long num = _color_list.getNum();
  WSDcolor*  col = NULL;
  for(i=0; i<num; i++){
    col = (WSDcolor*)_color_list[i];
    short id = col->getId();
    if (id == no){
      _cache_table2[hval] = col;
      return col;
    }
  }
  return NULL;
}
WSDcolor* WSCcolorSet::getColor(char* colname){
  if (colname[0] == 'D' && !strncmp("DEF",colname,3)){
    long no = -atoi(&colname[3]);
    return getColor(no);
  }

  long hval = WSGFgetHashValue(colname);
  if (_cache_table[hval] != NULL){
    char* name = _cache_table[hval]->getSrc();
    if (colname[0] == name[0] && !strcmp(colname,name) ){
      return _cache_table[hval];
    }
  }
  long i;
  long num = _color_list.getNum();
  WSDcolor* col = NULL;
  for(i=0; i<num; i++){
    col = (WSDcolor*)_color_list[i];
    if (!strcmp(col->getSrc(),colname)){
	  _cache_table[hval] = col;
      return col;
    }
  }
  if (_color_create_handler != NULL){
    col = _color_create_handler();
    col->setColorName(colname);
    col->setId(_local_cno);
    _color_list.add((void*)col);
    _cache_table[hval] = col;
    _local_cno ++;
    return col;
  }
  return NULL;
}
char* WSCcolorSet::getColorName(short no){
  if (no < 1){
    if (no != 0){
static char buffer[32];
      sprintf(buffer,"DEF%d",-no);
      return buffer;
    }else{
      return "";
    }
  }
  long hval = no % WS_MAX_HASH_VALUE;
  if (_cache_table2[hval] != NULL){
    short id = _cache_table2[hval]->getId();
    if (id == no){
      return _cache_table2[hval]->getSrc();
    }
  }
//  if (no < 1){
//    return "";
//  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (col->getId() == no){
	  _cache_table2[hval] = col;
      return col->getSrc();
    }
  }
  return "";
}
short WSCcolorSet::getStaticColorNo(char* colname){
  if (colname[0] == 'D' && !strncmp("DEF",colname,3)){
    return -atoi(&colname[3]);
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (col->getId() > 1023 && !strcmp(colname,col->getSrc())){
      return col->getId();
    }
  }
  if (_color_create_handler != NULL){
    WSDcolor* col = _color_create_handler();
    col->setColorName(colname);
    col->setId(_local_cno);
    _color_list.add((void*)col);
    _local_cno ++;
    return col->getId();
  }
  return -1;
}
short WSCcolorSet::getColorNo(char* colname){
  if (colname[0] == 'D' && !strncmp("DEF",colname,3)){
    return -atoi(&colname[3]);
  }
  long hval = WSGFgetHashValue(colname);
  if (_cache_table[hval] != NULL){
    char* name = _cache_table[hval]->getSrc();
    if (colname[0] == name[0] && !strcmp(colname,name) ){
      return _cache_table[hval]->getId();
    }
  }
  long i;
  long num = _color_list.getNum();
  WSDcolor* col2 = NULL;
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
	char* name = col->getSrc();
	if (name[0] == colname[0] && !strcmp(colname,name)){
      if (col->getId() < 1024){
        _cache_table[hval] = col;
        return col->getId();
	  }else{
	    col2 = col;
	  }
    }
  }
  if (col2 != NULL){
    _cache_table[hval] = col2;
    return col2->getId();
  }
  if (_color_create_handler != NULL){
    WSDcolor* col = _color_create_handler();
    col->setColorName(colname);
    col->setId(_local_cno);
    _color_list.add((void*)col);
    _local_cno ++;
    return col->getId();
  }
  return -1;
}
#if 0
short WSCcolorSet::getDefaultForeColorNo(){
  return _default_fg;
}
short WSCcolorSet::getDefaultBackColorNo(){
  return _default_bg;
}
WSDcolor* WSCcolorSet::getDefaultForeColor(){
  if (_default_fg_color != NULL){
    return _default_fg_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_fg == col->getId()){
      _default_fg_color = col;
      return col;
    }
  }
  return NULL;
}
WSDcolor* WSCcolorSet::getDefaultBackColor(){
  if (_default_bg_color != NULL){
    return _default_bg_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_bg == col->getId()){
      _default_bg_color = col;
      return col;
    }
  }
  return NULL;
}
long WSCcolorSet::setDefaultForeColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_fg = no;
  _default_fg_color = NULL;
  return WS_NO_ERR;
}
long WSCcolorSet::setDefaultBackColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_bg = no;
  _default_bg_color = NULL;
  return WS_NO_ERR;
}
#endif
WSClistData* WSCcolorSet::getColorList(){
  return &_color_list;
}
WSCbool WSCcolorSet::existColor(short no){
  if (no < 1){
    return False;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (col->getId() == no){
      return True;
    }
  }
  return False;
}
long WSCcolorSet::setCreateHandler(WSDcolor* (*hd)()){
  _color_create_handler = hd;
  return WS_NO_ERR;
}
void WSCcolorSet::addColor(WSDcolor* color){
  _color_list.add((void*)color);
}
void WSCcolorSet::delColor(WSDcolor* color){
  long i;
  _color_list.del((void*)color);
  for(i=0; i<WS_MAX_HASH_VALUE; i++){
    if (_cache_table[i] == color ){
      _cache_table[i] = NULL;
    }
    if (_cache_table2[i] == color ){
      _cache_table2[i] = NULL;
    }
  }
}
short WSGFcolor(char* colname){
  long no = atol(colname);
  if (no != 0){
    if (no < 1){
      return -1;
    }
    return no;
  }else{
    return WSGIappColorSet()->getStaticColorNo(colname);
  }
}
short WSGFindexColor(char* colname){
  long no = atol(colname);
  if (no != 0){
    if (no < 0){
      return -1;
    }
    return no;
  }else{
    return WSGIappColorSet()->getColorNo(colname);
  }
}
char* WSGFcolorName(short cno){
  return WSGIappColorSet()->getColorName(cno);
}
#if 0
short WSCcolorSet::getDefaultTopShadowColorNo(){
  return _default_ts;
}
long WSCcolorSet::setDefaultTopShadowColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_ts = no;
  _default_ts_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultTopShadowColor(){
  if (_default_ts_color != NULL){
    return _default_ts_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_ts == col->getId()){
      _default_ts_color = col;
      return col;
    }
  }
  return NULL;
}
short WSCcolorSet::getDefaultBottomShadowColorNo(){
  return _default_bs;
}
long WSCcolorSet::setDefaultBottomShadowColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_bs = no;
  _default_bs_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultBottomShadowColor(){
  if (_default_bs_color != NULL){
    return _default_bs_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_bs == col->getId()){
      _default_bs_color = col;
      return col;
    }
  }
  return NULL;
}
short WSCcolorSet::getDefaultMenuForeColorNo(){
  return _default_mfg;
}
long WSCcolorSet::setDefaultMenuForeColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_mfg = no;
  _default_mfg_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultMenuForeColor(){
  if (_default_mfg_color != NULL){
    return _default_mfg_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_mfg == col->getId()){
      _default_mfg_color = col;
      return col;
    }
  }
  return NULL;
}

short WSCcolorSet::getDefaultMenuBackColorNo(){
  return _default_mbg;
}
long WSCcolorSet::setDefaultMenuBackColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_mbg = no;
  _default_mbg_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultMenuBackColor(){
  if (_default_mbg_color != NULL){
    return _default_mbg_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_mbg == col->getId()){
      _default_mbg_color = col;
      return col;
    }
  }
  return NULL;
}
short WSCcolorSet::getDefaultDarkBackColorNo(){
  return _default_dbg;
}
long WSCcolorSet::setDefaultDarkBackColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_dbg = no;
  _default_dbg_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultDarkBackColor(){
  if (_default_dbg_color != NULL){
    return _default_dbg_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_dbg == col->getId()){
      _default_dbg_color = col;
      return col;
    }
  }
  return NULL;
}
short WSCcolorSet::getDefaultWorkBackColorNo(){
  return _default_wbg;
}
long WSCcolorSet::setDefaultWorkBackColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_wbg = no;
  _default_wbg_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultWorkBackColor(){
  if (_default_wbg_color != NULL){
    return _default_wbg_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_wbg == col->getId()){
      _default_wbg_color = col;
      return col;
    }
  }
  return NULL;
}

short WSCcolorSet::getDefaultMenuSelectColorNo(){
  return _default_msc;
}
long WSCcolorSet::setDefaultMenuSelectColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_msc = no;
  _default_msc_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultMenuSelectColor(){
  if (_default_msc_color != NULL){
    return _default_msc_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_msc == col->getId()){
      _default_msc_color = col;
      return col;
    }
  }
  return NULL;
}

short WSCcolorSet::getDefaultMenuTopShadowColorNo(){
  return _default_mts;
}
long WSCcolorSet::setDefaultMenuTopShadowColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_mts = no;
  _default_mts_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultMenuTopShadowColor(){
  if (_default_mts_color != NULL){
    return _default_mts_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_mts == col->getId()){
      _default_mts_color = col;
      return col;
    }
  }
  return NULL;
}
short WSCcolorSet::getDefaultMenuBottomShadowColorNo(){
  return _default_mbs;
}
long WSCcolorSet::setDefaultMenuBottomShadowColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_mbs = no;
  _default_mbs_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultMenuBottomShadowColor(){
  if (_default_mbs_color != NULL){
    return _default_mbs_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_mbs == col->getId()){
      _default_mbs_color = col;
      return col;
    }
  }
  return NULL;
}

short WSCcolorSet::getDefaultBarShadowColorNo(){
  return _default_bsc;
}
long WSCcolorSet::setDefaultBarShadowColorNo(short no){
  if (no < 1){
     return WS_ERR;
  }
  _default_bsc = no;
  _default_bsc_color = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultBarShadowColor(){
  if (_default_bsc_color != NULL){
    return _default_bsc_color;
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_bsc == col->getId()){
      _default_bsc_color = col;
      return col;
    }
  }
  return NULL;
}

#endif
short WSCcolorSet::getDefaultColorNo(long kind){
  long no = -kind;
  if (no < 0 || no > WS_MAX_DF_COLORS-1){
    return 1;
  }
  return _default_cols[no];
}
long WSCcolorSet::setDefaultColorNo(long kind,short no){
  if (no < 1){
     return WS_ERR;
  }
  long no1 = -kind;
  if (no1 < 0 || no1 > WS_MAX_DF_COLORS-1){
    return WS_ERR;
  }
  _default_cols[no1] = no;
  _default_colors[no1] = NULL;
  return WS_NO_ERR;
}
WSDcolor* WSCcolorSet::getDefaultColor(long kind){
  long no = -kind;
  if (no < 0 || no > WS_MAX_DF_COLORS-1){
    return NULL;
  }
  if (_default_colors[no] != NULL){
    return _default_colors[no];
  }
  long i;
  long num = _color_list.getNum();
  for(i=0; i<num; i++){
    WSDcolor* col = (WSDcolor*)_color_list[i];
    if (_default_cols[no] == col->getId()){
      _default_colors[no] = col;
      return col;
    }
  }
  return NULL;
}
