//
// 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 <WSCblink.h>
#include <WSDtimer.h>
#include <WSCnwbase.h>

static WSCblink* _the_app_blink = NULL;
WSCblink* WSGIappBlink(){
  if (_the_app_blink == NULL){
    _the_app_blink = new WSCblink();
  }
  return _the_app_blink;
}
WSCblink::WSCblink(){
  _timer_id = 0;
  _clock = 0;
}
WSCblink::~WSCblink(){
  if (_timer_id != 0){
    WSGIappTimer()->delTimerProc(_timer_id);
  }
}
WSCbool WSCblink::getBlinkFore(long rate){
  return (_clock/rate) % 2;
}
void WSCblink::_blink_proc(WSCuchar clk,void* ptr){
  WSCblink* obj = (WSCblink*)ptr;
  WSClistData* clients = &(obj->_blink_clients);
  WSClistData* rates = &(obj->_blink_rates);
  WSClistData* refreshes = &(obj->_blink_refreshes);
  long num = clients->getNum();
  obj->_clock = ~clk;

  long i;
  for(i=0; i < num; i++){
    WSCbase* client = (WSCnwbase*)(*clients)[i];
    long rate = (long)(*rates)[i];
    long refresh = (long)(*refreshes)[i];
    if (!((obj->_clock +1) % rate)){
      if (refresh == False){
        client->clear();
        client->setAbsoluteDraw(True);
        client->draw();
        client->drawGriphand();
      }else{
        client->redraw();
      }
    }
  }
}
long WSCblink::addBlinkInstance(WSCbase* base,unsigned char rate,WSCbool fl){
  _blink_clients.add((void*)base);
  long rt = (long)rate;
  _blink_rates.add((void*)rt);
  long fl2 = (long)fl;
  _blink_refreshes.add((void*)fl2);

  if (_timer_id == 0){
    _timer_id = WSGIappTimer()->addTimerProc(_blink_proc,WS250MS,this);
  }
  return WS_NO_ERR;
}
long WSCblink::delBlinkInstance(WSCbase* base){
  WSCnwbase* nwbase = (WSCnwbase*)base->cast("WSCnwbase");
  if (nwbase == NULL){
    return WS_ERR;
  }

  long pos = _blink_clients.del((void*)base);
  _blink_rates.delPos(pos);
  _blink_refreshes.delPos(pos);

  if (_blink_clients.getNum() == 0){
    WSGIappTimer()->delTimerProc(_timer_id);
    _timer_id = 0;
  }
  return WS_NO_ERR;
}
WSClistData* WSCblink::getBlinkClients(){
  return &_blink_clients;
}

