#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <WSDappDev.h>
#include <WSCbaseList.h>
#include <WSCRbaseList.h>
#include <WSCconductor.h>
#include <WSCverbList.h>
#include <newwin000.h>

extern WSCstring ipaddr;

void timerop(WSCbase* object){
  //do something...
  WSClistData* rilist = WSGIappObjectList()->getRemoteInstanceList();
  long num = rilist->getNum();
  WSCindexData addrs;
  long i;
  for(i=0; i<num; i++){
    WSCremoteInstanceData* item =
        (WSCremoteInstanceData*)(*rilist)[i];
    long val = (long)item->getPort();
    if (!strcmp(item->getAddr(),"")){
      addrs.setData(ipaddr.getString(),(void*)(val));
    }else{
      addrs.setData(item->getAddr(),(void*)(val));
    }
  }

  WSCindexData deladdrs;
  WSCRbaseList* target = new WSCRbaseList();
  num = addrs.getNum();
  for(i=0; i<num; i++){
    char* addr = addrs.getIndex(i);
    long port = (long)addrs.getData(i);
    target->setAddr(addr);
    target->setPort((WSCushort)port);
    WSCbool alive = target->checkAlive();
    if (alive == False){
      deladdrs.setData(addr,(void*)port);
    }
  }

  num = deladdrs.getNum();
  for(i=0; i<num; i++){
    char* addr = addrs.getIndex(i);
    long port = (long)addrs.getData(i);
    long j;
    long dnum = rilist->getNum();
    for(j=0; j<dnum; j++){
      WSCremoteInstanceData* item =
        (WSCremoteInstanceData*)(*rilist)[j];
      if (!strcmp(item->getAddr(),"")){
        if (port == (long)item->getPort() && !strcmp(ipaddr.getString(),addr)){
//printf("timerop.cpp deleted addr=%s port=%d\n",addr,port);
          rilist->delPos(j);
          WSGIappObjectList()->setRemoteInstanceListUpdated(True);
          delete item;
          dnum--;
          j--;
        } 
      }else{
        if (port == (long)item->getPort() && !strcmp(item->getAddr(),addr)){
//printf("timerop.cpp deleted addr=%s port=%d\n",addr,port);
          rilist->delPos(j);
          WSGIappObjectList()->setRemoteInstanceListUpdated(True);
          delete item;
          dnum--;
          j--;
        } 
      } 
    }
    if (dnum == 0){ 
      newverb_000->delAll();
      newverb_000->updateList();
    }
  }
  if (WSGIappObjectList()->getRemoteInstanceListUpdated() != False){
    WSClistData* rlist = WSGIappObjectList()->getRemoteInstanceList();
    long num = rlist->getNum();
    long i;
    newverb_000->delAll();
    for(i=0; i<num; i++){
      WSCremoteInstanceData* item = 
        (WSCremoteInstanceData*)rlist->getData(i);
//printf("wsagent.. item->addr=%s\n",item->getAddr().getString());
      WSCstring str;
      if (!strcmp(item->getAddr(),"")){
        str << ipaddr.getString() << "," << item->getPort() << "," <<
            item->getPublicInstanceName();
      }else{
        str << item->getAddr() << "," << item->getPort() << "," <<
            item->getPublicInstanceName();
      }
      newverb_000->addItem(str);
    }
    newverb_000->updateList();
    WSGIappDev()->update(); 
  }

//update された場合のみ、IPのインスタンスのみをUDP で送る。
static long cnt = 0;
  cnt++;
  if (WSGIappObjectList()->getRemoteInstanceListUpdated() != False || cnt % 10 == 0){
    WSGIappObjectList()->setRemoteInstanceListUpdated(False);
    WSClistData* rlist = WSGIappObjectList()->getRemoteInstanceList();
    long num = rlist->getNum();
    long i;
    for(i=0; i<num; i++){
      WSCremoteInstanceData* item = 
        (WSCremoteInstanceData*)rlist->getData(i);
      WSCuchar buffer[256];
      WSCushort port = item->getPort();
      buffer[0] = 'w';
      buffer[1] = 's';
      buffer[2] = 'a';
      buffer[3] = 'A'; //add..
      buffer[4] = port & 0xff;
      buffer[5] = port >> 8;
      if (!strcmp(item->getAddr(),"")){
        strncpy((char*)&buffer[6],ipaddr.getString(),26);
      }else{
        strncpy((char*)&buffer[6],item->getAddr(),26);
      }
      buffer[31] = 0;
      strncpy((char*)&buffer[32],item->getClassName(),48);
      buffer[79] = 0;
      strncpy((char*)&buffer[80],item->getInstanceName(),64);
      buffer[143] = 0;
      strncpy((char*)&buffer[144],item->getPublicInstanceName(),64);
      buffer[207] = 0;
//printf("send--------!!!! %x %x\n",buffer[1],buffer[0]);
      long ret = newvudp_000->write(buffer,256);
//printf("send------------!!!! %d %s %s send_len=%d\n",port,(char*)&buffer[6],(char*)item->getInstanceName(),ret);
      if (ret != 256){
        long total_len = ret;
        long cnt = 0;
        while(1){
          long ret = newvudp_000->write(&buffer[total_len],256-total_len);
//printf("send2-----------!!!! %d %s %s send_len=%d\n",port,(char*)&buffer[6],(char*)item->getInstanceName(),ret);
          if (ret < 0){
            return;
          }
          if (total_len + ret != 256){
            cnt++;
            total_len += ret; 
          }else{
            break;
          }
          if (cnt > 10){
            return;
          }
        }
      }
    }
  }
}
static WSCfunctionRegister  op("timerop",(void*)timerop);
