//
// 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 <WSCvssocket.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSCblink.h>
#include <WSCcolorSet.h>
#include <WSCimageSet.h>
#include <WSDdev.h>
#include <WSDcolor.h>
#include <WSCfontSet.h>
#include <WSDappDev.h>

WSMFguiClassInitialize(WSCvssocket, WSCngbase);
WSMFversion(WSCvssocket, WSCngbase);

WSCvssocket::WSCvssocket(WSCbase* base, char* objname):
			WSCngbase(base, objname){
  _socket = NULL;
  _addr = WSGFstrdup("");
  _port = 9000;
  _on = False;
  _timeout = 60;
  _title_string.setString("Server\nSocket");

  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCvssocket);

    WSMFpropertyCreate(WSNip,      char*,   _addr,WSSip);
    WSMFpropertyCreate(WSNport,    WSCushort,   _port,WSSport);
    WSMFpropertyCreate(WSNtimeout, WSCulong,   _timeout,WSStimeout);
    WSMFpropertyCreate(WSNrunning, WSCbool,   _on,WSSrunning);
      WSMFpropertySetSelection(WSRbool3,WSRbool3D);

    WSMFaddTrigger(WSEV_ACTIVATE  );
  WSMFpropertyCreateEnd

}
WSMFproperty( WSCvssocket, WSNip, char*, _addr ,WSGFstrdup(""));
WSMFproperty( WSCvssocket, WSNport, WSCushort, _port ,9000);
WSMFproperty( WSCvssocket, WSNrunning, WSCbool, _on ,False);
WSMFproperty( WSCvssocket, WSNtimeout, WSCulong, _timeout ,60);

void WSCvssocket::setWorkWSNip(char* ip){
  if (_socket == NULL){
    _socket = WSDsocket::getNewInstance();
  }
  _socket->setAddr(ip); 
};
void WSCvssocket::getWorkWSNip(char**){};

void WSCvssocket::setWorkWSNport(WSCushort port){
  if (_socket == NULL){
    _socket = WSDsocket::getNewInstance();
  }
  _socket->setPort(port); 
};
void WSCvssocket::getWorkWSNport(WSCushort*){};

void WSCvssocket::setWorkWSNrunning(WSCbool fl){
  if (_socket == NULL){
    _socket = WSDsocket::getNewInstance();
  }
  if (getPropertyEditMode() != False){
    return;
  }
  if (fl == False){
    if (_socket->getAcceptStarted() != False){
      _socket->stopAcceptEx();
      _error_str = _socket->getLastError();
    }
  }else{
    if (_socket->getAcceptStarted() == False){
      _socket->setAddr(_addr); 
      _socket->setPort(_port); 
      _socket->setClTimeout(_timeout);
      _socket->setUserData(this);
      _socket->acceptEx(_accepted_work);
      _error_str = _socket->getLastError();
    }
  }
};
void WSCvssocket::getWorkWSNrunning(WSCbool*){};

void WSCvssocket::setWorkWSNtimeout(WSCulong timeout){
  if (_socket == NULL){
    _socket = WSDsocket::getNewInstance();
  }
  _socket->setClTimeout(timeout);
};
void WSCvssocket::getWorkWSNtimeout(WSCulong*){};



void WSCvssocket::onActivate(){
  execProcedure(WSEV_ACTIVATE);
}

WSCvssocket::~WSCvssocket() {
  if (_socket != NULL){
    delete _socket;
    _socket = NULL;
  }
  if (_addr != NULL){
    delete _addr;
    _addr = NULL;
  }
}

void WSCvssocket::_accepted_work(WSDsocket* sock,void* socket,WSCulong addr){
  WSCvssocket* _this = (WSCvssocket*)sock->getUserData();
  _this->_handle = socket;
  if (_this->_socket != NULL){
    _this->_socket->_set_dest_addr_(addr);
  }
  _this->onActivate();
  sock->close(socket);
}
long WSCvssocket::read(WSCuchar* buf,long size){
  if (_socket == NULL){
    return -1;
  }
  if (_handle == NULL){
    return -1;
  }
  long ret = _socket->read(_handle,buf,size);
  _error_str = _socket->getLastError();
  return ret;
}
long WSCvssocket::write(WSCuchar* buf,long size){
  if (_socket == NULL){
    return -1;
  }
  if (_handle == NULL){
    return -1;
  }
  long ret = _socket->write(_handle,buf,size);
  _error_str = _socket->getLastError();
  return ret;
}
WSCstring WSCvssocket::getDestAddr(){
  if (_socket == NULL){
    WSCstring tmp;
    return tmp;
  }
  return _socket->getDestAddr();
}
WSDsocket* WSCvssocket::getSocket(){
  return _socket;
}
void WSCvssocket::getErrorMsg(char* buffer,long size){
  if (size < 1){
    return;
  }
  strncpy(buffer,(char*)_error_str,size);
  buffer[size-1] = 0;
}
WSCstring WSCvssocket::getErrorMessage(){
  WSCstring ret;
  ret.setString(_error_str);
  return ret;
}

