//
// 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 <WSCimageSet.h>

static WSCimageSet* _the_app_image_list = NULL;

WSCimageSet* WSGIappImageSet(){
  if (_the_app_image_list == NULL){
    _the_app_image_list = new WSCimageSet();
  }
  return _the_app_image_list;
};


WSCimageSet::WSCimageSet(){
  _create_handler = NULL;
  _image_num = 1;
  long i;
  for(i=0; i<WS_MAX_HASH_VALUE; i++){
    _cache_table[i] = NULL;
    _cache_table2[i] = NULL;
  }
}

WSCimageSet::~WSCimageSet(){
   long i;
   long num = _image_list.getNum();
   for(i = 0; i<num; i++){
      WSDimage* img = (WSDimage*)_image_list[i];
      delete img;
   }
}

char* WSCimageSet::getImageName(short no){
  if (no == -1) return "";

  long i;
  long num = _image_list.getNum();
  for(i = 0; i<num; i++){
    WSDimage* img = (WSDimage*)_image_list[i];
    short id = img->getId();
    if (id == no){
      char* ret = img->getSrc();
      return ret;
    }
  }
  return "";
}


WSDimage* WSCimageSet::getImage(short 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 = _image_list.getNum();
  for(i = 0; i<num; i++){
    WSDimage* img = (WSDimage*)_image_list[i];
    short id = img->getId();
    if (id == no){
      _cache_table[hval] = img;
      return img;
    }
  }
  return NULL;
}

WSDimage* WSCimageSet::getImage(char* iname){
  long hval = WSGFgetHashValue(iname);
  if (_cache_table[hval] != NULL){
    char* name = _cache_table[hval]->getSrc();
    if (iname[0] == name[0] && !strcmp(iname,name) ){
      return _cache_table[hval];
    }
  }

  long i;
  long num = _image_list.getNum();
  for(i = 0; i<num; i++){
    WSDimage* img = (WSDimage*)_image_list[i];
    if (img->getSrc()[0] == iname[0] && !strcmp(img->getSrc(),iname)){
      _cache_table[hval] = img;
      return img;
    }
  }

  if (_create_handler != NULL){
    WSDimage* img = _create_handler();
    img->setImageName(iname);
    img->setId(_image_num);
    _image_num++;
    _image_list.add( (void*)img );
    _cache_table[hval] = img;
    return img;
  }
  return NULL;
}

short WSCimageSet::getImageNo(char* iname){
  long hval = WSGFgetHashValue(iname);
  if (_cache_table[hval] != NULL){
    char* name = _cache_table[hval]->getSrc();
    if (iname[0] == name[0] && !strcmp(iname,name) ){
      short ret = _cache_table[hval]->getId();
      return ret;
    }
  }

  long i;
  long num = _image_list.getNum();
  for(i = 0; i<num; i++){
    WSDimage* img = (WSDimage*)_image_list[i];
    if (img->getSrc()[0] == iname[0] && !strcmp(img->getSrc(),iname)){
      _cache_table[hval] = img;
      short ret = img->getId();
      return ret;
    }
  }

  if (_create_handler != NULL){
    WSDimage* img = _create_handler();
    img->setImageName(iname);
    img->setId(_image_num);
    img->getValue1();
    _image_num++;
    _image_list.add( (void*)img );
    _cache_table[hval] = img;
    short ret = img->getId();
    return ret;
  }
  return -1;
}
long WSCimageSet::destroyImage(short no){
  WSDimage* img = getImage(no);
  if (img != NULL){
    img->destroyImage();
  }
  return WS_NO_ERR;
}
long WSCimageSet::destroyImage(char* iname){
  WSDimage* img = getImage(iname);
  if (img != NULL){
    img->destroyImage();
  }
  return WS_NO_ERR;
}
long WSCimageSet::update(char* iname){
  WSDimage* img = getImage(iname);
  if (img != NULL){
    img->destroyImage();
    img->getValue1();
  }
  return WS_NO_ERR;
}

long WSCimageSet::destroyAllImage(){
  long i;
  long num = _image_list.getNum();
  for(i = 0; i<num; i++){
    WSDimage* img = (WSDimage*)_image_list[i];
    img->destroyImage();
  }
  return WS_NO_ERR;
}
long WSCimageSet::setCreateHandler(WSDimage* (*hd)()){
  _create_handler = hd;
  return WS_NO_ERR;
}
short WSGFimage(char* cname){
  return WSGIappImageSet()->getImageNo(cname);
}
char* WSGFimageName(short pno){
  return WSGIappImageSet()->getImageName(pno);
}
long WSCimageSet::setDefaultImageHandle(char* iname,void* handle){
  _default_image_handles.setData(iname,handle);
  return WS_NO_ERR;
}
void* WSCimageSet::getDefaultImageHandle(char* iname){
  return _default_image_handles.getData(iname);
}
