//
// 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 <WSDappDev.h>
#include <WSCbaseList.h>
#include <WSDmessage.h>
#include <WSCbase.h>
#include <WSDenv.h>
#include <WSCguiPolicy.h>

WSDappDev*    WSDappDev::_instance = NULL;
WSMFclassInit(WSDappDev,WSDdev);
WSCbool WSDappDev::_trace_output = False;
WSCbool WSDappDev::getInstanceExist(){
  if (_instance != NULL){
    return True;
  }else{
    return False;
  }
}
void WSDappDev::setInstance(WSDappDev* dev){
  _instance = dev;
}

WSDappDev::WSDappDev(){
  if (_instance != NULL){
WSMFtrace("Error! too many instances of WSDappDev.\n");
    exit(1);
  }
  _modal_client = NULL;
  _modal_proc = NULL;
  _iprm = 0;
  _cprm = 0;
  _policy = -1;
  _focus_dialog = NULL;
  _selection_owner = NULL;
  _mode = WS_MODE_NORMAL;
  _alt_context = NULL;
  _alt_context2 = NULL;
  _under_exec_init = False;
}

WSDappDev::~WSDappDev(){
//  destroy();
}
int WSDappDev::getArgc(){
  return _iprm;
}
char** WSDappDev::getArgv(){
  return _cprm;
}

void WSDappDev::setInstanceName(char* name){
  _name.setString(name);
}

char* WSDappDev::getInstanceName(){
  return _name.getString();
}

long WSDappDev::initialize(){
  setInstance(this);
  return WS_NO_ERR;
}

void WSDappDev::_trace_msg(char* data){
//printf("WSDappDev::_trace_msg!!!  here\n");
  if (data[0] == '1'){
//printf("WSDappDev::_trace_msg!!!\n");
    _trace_output = True;
    WSDmessage::extSendMessage(NULL,"TR-START","0");
  }else{
    _trace_output = False;
  }
}

WSCbool WSDappDev::_init_executed = False;
WSClistData*    WSDappDev::_init_handler = NULL;
WSClistData* WSDappDev::getInitHandler(){
  if (_init_handler == NULL){
    _init_handler = new WSClistData();
  }
  return _init_handler;
}

long WSDappDev::execInitHandler(){
dbprintf("WSDappDev::execInitHandler() %s:%d start \n",__FILE__,__LINE__);
  if (_instance == NULL){
WSMFtrace("Error! No instance of WSDappDev exists.\n");
    exit(0);
    return WS_ERR;
  }
  _under_exec_init = True;
  _init_executed = True;
  long num = getInitHandler()->getNum();
  long i;
  for(i=0; i< num; i++){
    void(*hd)() = (void(*)())getInitHandler()->getData(i);
    hd();
  }
  WSGIappObjectList()->execInitialize();

  WSDmessage* msg1 = WSDmessage::getNewInstance();
  msg1->setupMessage(getInstanceName(),_trace_msg);
dbprintf("WSDappDev::execInitHandler() %s:%d done. \n",__FILE__,__LINE__);
  _under_exec_init = False;
  return WS_NO_ERR;
}

void WSDappDev::setInitHandler(void (*hd)() ){
  if (_instance == NULL){
    getInitHandler()->add((void*)hd);
    return ;
  }
  hd();
}

WSCushort WSDappDev::getWidth(){
  return (WSCushort)1024;
}

WSCushort WSDappDev::getHeight(){
  return (WSCushort)768;
}

WSCbool WSDappDev::getTraceMode(){
  return _trace_output;
}

void WSDappDev::setTraceMode(WSCbool fl){
  _trace_output = fl;
}

static WSDappDev* (*_create_handler)() = NULL;
void WSDappDev::setCreateInstanceHandler( WSDappDev* (*hd)()){
  _create_handler = hd;
}
static WSDappDev* theAppDev = NULL;
WSDappDev* WSGIappDev(){
  if (theAppDev == NULL){
    if (_create_handler == NULL){
      return NULL;
WSMFtrace("WSGIappDev() ERROR. cannot create WSDappDev class instance.\n");
    }
    theAppDev = _create_handler();
  }
  return theAppDev;
}

//void WSDappDev::setLockStatus(WSCbool fl){
//  _lock_status = fl;
//}
//
//WSCbool WSDappDev::getLockStatus(){
//  return _lock_status;
//}
void WSDappDev::setModalClient(WSCbase* client){
  _modal_client = client;
}
WSCbase* WSDappDev::getModalClient(){
  return _modal_client;
}
void WSDappDev::update(){
WSMFtrace("WSDappDev::update() This system does not supprt.\n");
}
void WSDappDev::setModalProc(void(*proc)(WSDdev*,long,void*)){
  _modal_proc = (void*)proc;
}
void* WSDappDev::getModalProc(){
  return _modal_proc;
}
void WSDappDev::setSelectionOwner(WSCbase* owner){
  if ( _selection_owner != owner){
    WSCbase* bk = _selection_owner;
    _selection_owner = owner;
    if (bk != NULL){
      bk->onSelectionChange(False);
    }
    if (_selection_owner != NULL){
      owner->onSelectionChange(True);
    }
  }
}
WSCbase* WSDappDev::getSelectionOwner(){
  return _selection_owner;
}

void WSDappDev::setGuiPolicy(long val,WSCbool create_event){
  WSGIappGuiPolicy()->setGuiPolicy(val,create_event);
#if 0
  _policy = val;
  if (!(val & WS_POLICY_ORIGINAL) && 
      !(val & WS_POLICY_WINDOWS)){
    _policy |= WS_POLICY_WINDOWS;
  }
  if ((val & WS_POLICY_ORIGINAL) && 
      (val & WS_POLICY_WINDOWS)){
    long val2 = ~WS_POLICY_ORIGINAL;
    _policy &= val2;
  }
  if (create_event != False){
    WSGIappObjectList()->execEvent(WSEV_GUI_POLICY_CH,(void*)_policy);
  }
#endif
}
long WSDappDev::getGuiPolicy(){
  return WSGIappGuiPolicy()->getGuiPolicy();
#if 0
  if (_policy == -1){
    return (WS_POLICY_WINDOWS | WS_POLICY_GRADATION);
  }
  return _policy;
#endif
}

void WSDappDev::setFocusDialog(WSCbase* client,WSCbool fl){
  if (fl == False && _focus_dialog == client){
    _focus_dialog = NULL;
    return;
  }
  if (fl != False){
    _focus_dialog = client;
    return;
  }
}

WSCbase* WSDappDev::getFocusDialog(){
  return _focus_dialog;
}
void WSDappDev::addMenu(WSCbase* menu){
  _pld_menu_list.add((void*)menu);
}
void WSDappDev::delMenu(WSCbase* menu){
  _pld_menu_list.del((void*)menu);
}
WSClistData& WSDappDev::getMenuList(){
  return _pld_menu_list;
}
void WSDappDev::exit(long val){
  ::exit(val);
}
void WSDappDev::setMode(long mode){
  _mode = mode;
}
long WSDappDev::getMode(){
  return _mode;
}
void WSDappDev::setContext(void* context){
  _alt_context = context;
}
void* WSDappDev::getContext(){
  return _alt_context;
}
void WSDappDev::setContext2(void* context){
  _alt_context2 = context;
}
void* WSDappDev::getContext2(){
  return _alt_context2;
}

WSCstring WSDappDev::getExtGuiPolicyName(){
  return WSGIappGuiPolicy()->getExtGuiPolicyName();
#if 0
  return _ext_policy_name;
#endif
}
WSCbool WSDappDev::getExtGuiPolicySelected(){
  return WSGIappGuiPolicy()->getExtGuiPolicySelected();
#if 0
  if (_policy & WS_POLICY_OTHER){
    return True;
  }
  return False;
#endif
}
void WSDappDev::setExtGuiPolicy(char* pname,WSCbool fl){
  WSGIappGuiPolicy()->setExtGuiPolicy(pname,fl);
#if 0
  if (pname == NULL || !strcmp(pname,"")){
    _ext_policy_name.setString("");
    _policy &= ~WS_POLICY_OTHER;
    _current_policy_fn_list = NULL;
  }else{
    _ext_policy_name.setString(pname);
    _policy |= WS_POLICY_OTHER;
    _current_policy_fn_list = (WSCindexData*)_ext_policy_list[_ext_policy_name.getString()];
  }
  if (fl != False){
    WSGIappObjectList()->execEvent(WSEV_GUI_POLICY_CH,(void*)_policy);
    WSGIappObjectList()->execUpdate();
  }
#endif
}
void WSDappDev::setExtGuiPolicyProc(char* plname,char* pname,void(*fn)(void*)){
  WSGIappGuiPolicy()->setExtGuiPolicyProc(plname,pname,fn);
#if 0
  if (plname == NULL || pname == NULL){
    return;
  }

  WSCindexData* plist = (WSCindexData*)_ext_policy_list[plname];
  if (plist == NULL){
    plist = new WSCindexData;
    _ext_policy_list[plname] = (void*)plist;
  }
  if (plist == NULL){
    return;
  }
  (*plist)[pname] = (void*)fn;
#endif
}

void* WSDappDev::getExtGuiPolicyProc(char* pname){
  return WSGIappGuiPolicy()->getExtGuiPolicyProc(pname);
#if 0
  if (getExtGuiPolicySelected() == False){
    return NULL;
  }
  if (_current_policy_fn_list == NULL){
    _current_policy_fn_list = (WSCindexData*)_ext_policy_list[_ext_policy_name.getString()];
  }
  if (_current_policy_fn_list == NULL){
    return NULL;
  }
  return (*_current_policy_fn_list)[pname];
#endif
}
WSCindexData* WSDappDev::getExtGuiPolicyList(){
  WSGIappGuiPolicy()->getExtGuiPolicyList();
#if 0
  return &_ext_policy_list;
#endif
}
WSCbool WSDappDev::getUnderExecInitialize(){
  return _under_exec_init;
}
WSCbool WSDappDev::getInitializeExecuted(){
  return _init_executed;
}
