//
// Copyright (C) 1999-2002 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 <win/WSDwinAppDev.h>
#include <win/WSDwinMessage.h>
#include <WScom.h>
#include <WSClistData.h>

WSMFclassInit(WSDwinMessage,WSDmessage);

WSDmessage* _winclient_msg_create(){
  return new WSDwinMessage;
}

class _winclient_msg_init {
  public: _winclient_msg_init(){
    WSDmessage::setCreateHandler(_winclient_msg_create);
    WSDmessage::_setup_ext_send_msg_proc((void*)WSDwinMessage::extSendMessage,
                                         (void*)WSDwinMessage::extSendNewMessage);
  };
};
_winclient_msg_init  _winclient_msg_init_execute;

WSClistData _msg_instance_list;

WSCbool WSDwinMessage::_is_exist(WSDwinMessage* inst){
  long i;
  long num = _msg_instance_list.getNum();
  for(i=0; i<num; i++){
    WSDwinMessage* p = (WSDwinMessage*)_msg_instance_list[i];
    if (p == inst){
      return True;
    }
  }
  return False;
}

int WSDwinMessage::receiveMessage(WSDwinMessage* p,void* val){
  ATOM atom = (ATOM)val;
  char buffer[4096];
  buffer[4094] = 0;
  buffer[4095] = 0;
  long ret = GlobalGetAtomName(atom,buffer,4094);
  GlobalDeleteAtom(atom);
  if (ret == 0){
    return False;
  } 
  if (_is_exist(p)){
    p->sendMessage(buffer);
    return True;
  }
  return False;
}

WSDwinMessage::WSDwinMessage(){
  _hkey = 0;
  DWORD dispos;
  LONG ret = RegCreateKeyEx(HKEY_CURRENT_USER,"SoftWare\\WideStudio\\WSTEMP",0,"",REG_OPTION_VOLATILE,
                   KEY_ALL_ACCESS,NULL,&_hkey,&dispos);
//printf("WSDwinMessage::WSDwinMessage ret=%d %d\n",ret,ERROR_SUCCESS);
  if (ret == ERROR_SUCCESS){
    _msg_instance_list.add((void*)this);
  }
}

WSDwinMessage::~WSDwinMessage(){
  if (_hkey != 0){
    _msg_instance_list.del((void*)this);
    RegDeleteValue(_hkey,_id.getString());
    WSCstring str = _id;
    str << "#THIS#";
    RegDeleteValue(_hkey,str.getString());
  }
}

long WSDwinMessage::initialize(){
//printf("WSDwinMessage::initialize _hkey=0x%x\n",_hkey);
  if (_hkey != 0){
    HWND hwnd = WSGIwinAppDev()->getHWND();
    RegSetValueEx(_hkey,_id.getString() ,0,REG_DWORD,(const BYTE*)&hwnd,sizeof(DWORD));
    WSCstring str = _id;
    str << "#THIS#";
    WSDwinMessage* ptr = this;
    RegSetValueEx(_hkey,str.getString() ,0,REG_DWORD,(const BYTE*)&ptr,sizeof(DWORD));
  }
  return 0 ;
}

int WSDwinMessage::extSendNewMessage(char* disp,char *message,char *data){
  return WSDwinMessage::extSendMessage(disp,message,data);
}


int WSDwinMessage::extSendMessage(char* dispname, char *message, char *data){
  WPARAM wparam;
  LPARAM lparam;
  HWND hwnd = NULL;
  HKEY hkey;
  DWORD dispos;
  LONG ret = RegCreateKeyEx(HKEY_CURRENT_USER,"SoftWare\\WideStudio\\WSTEMP",0,"",REG_OPTION_VOLATILE,
                   KEY_ALL_ACCESS,NULL,&hkey,&dispos);
//printf("WSDwinMessage::extSendMessage hkey=0x%x\n",hkey);

  if (ret != ERROR_SUCCESS){
    return WS_ERR;
  }

  if (hkey != 0){
    DWORD type;
    DWORD size = sizeof(DWORD);
    LONG ret = RegQueryValueEx(hkey,message,0,&type,(BYTE*)&hwnd,&size);
    if (ret != ERROR_SUCCESS){
      return WS_ERR;
    }
    WSCstring str(message);
    str << "#THIS#";
    RegQueryValueEx(hkey,str.getString() ,0,&type,(BYTE*)&wparam,&size);
    if (ret != ERROR_SUCCESS){
      return WS_ERR;
    }
  }
  ATOM atom = GlobalAddAtom(data);
  lparam = (LPARAM)atom; 
  DWORD result;
  ret = SendMessageTimeout(hwnd,WM_USER,wparam,lparam,
                                SMTO_NORMAL,1000,&result);
  if(ret == False){
    GlobalDeleteAtom(atom);
//printf("send error.. delete atom..\n");
  }
  return 0;
}

void WSDwinMessage::sendMessage(char *data){
  if (_exec_action != NULL){
    _exec_action(data);
  }else{
    _exec_action2(data,_data);
  }
}

