//
// 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 <nx/WSDnxAppDev.h>
#include <WSDfont.h>
#include <WSDdev.h>
#include <nx/WSDnxMouse.h>
#include <nx/WSDnxColor.h>
#include <nx/WSDnxDraw.h>
#include <nx/WSDunixSemaphore.h>
#include <nx/WSDunixMutex.h>
#include <nx/WSDunixThread.h>
#include <nx/WSnxcom.h>


int main1(int argc,char** argv){

dbprintf("Main.cpp: main1() %s:%d stargetd.\n",__FILE__,__LINE__);
   WSDdev::setDraw(new WSDnxDraw());

   WSDappDev* app = WSGIappDev();
   WSDnxAppDev* nxApp = (WSDnxAppDev*)app->cast("WSDnxAppDev");
   if (argc != 0){
     nxApp->setInitPrm(argc,argv);
   }
   nxApp->initialize();
   WSGInxAppMouse()->initialize();

   extern void _nxFont_init();
   _nxFont_init();

#ifdef TDBG
dbprintf("main init done.:%d\n",WSGFdiffTimePoint());
WSMFtrace("main init done.:%d\n",WSGFdiffTimePoint());
#endif
dbprintf("Main.cpp: main1() %s:%d done.\n",__FILE__,__LINE__);
  return 0;
}

int WSGFwsInitialize(){
  main1(0,NULL);
  return 0;
}

#ifdef WS_OWN_EVENT_LOOP

WSClistData _data;
WSDsemaphore* sem = NULL;
WSDmutex* mutex = NULL;
WSCbool WSGFnxInitializeEventLoop(){
  sem = WSDsemaphore::getNewInstance();
  if (sem == NULL){
    return False;
  }
  sem->initialize();
  mutex = WSDmutex::getNewInstance();
  if (mutex == NULL){
    return False;
  }
  mutex->initialize();
  return True;
}
WSCbool WSGFnxSendEvent(WSDnxEvent* ev){
  if (ev == NULL){
    return False;
  }
  if (sem == NULL){
    return False;
  }
  if (mutex == NULL){
    return False;
  }
  WSDnxEvent* ev2 = new WSDnxEvent;
  memcpy(ev2,ev,sizeof(WSDnxEvent));
  mutex->lock();
  _data.add((void*)ev2);
  mutex->unlock();

  sem->unlock();

  return True;
}

WSCbool WSGFnxGetNextEvent(WSDnxEvent* ev,WSCbool wait){
  if (ev == NULL){
    return False;
  }
  if (sem == NULL){
    return False;
  }
  if (mutex == NULL){
    return False;
  }

  if (wait != False){
    sem->lock();
  }

  mutex->lock();
  long num = _data.getNum();
  if (num == 0){
    mutex->unlock();
    return False;
  }
  WSDnxEvent* ev2 = (WSDnxEvent*)_data[0];
  _data.delPos(0);
  mutex->unlock();
  if (ev2 == NULL){
    return False;
  }
  memcpy(ev,ev2,sizeof(WSDnxEvent));
  delete ev2;
  return True;
}
#endif //WS_OWN_EVENT_LOOP

char* cvt_table[]={
"\xe3\x81\x8b\xe3\x82\x99","\xe3\x81\x8c", //GA
"\xe3\x81\x8d\xe3\x82\x99","\xe3\x81\x8e", //GI
"\xe3\x81\x8f\xe3\x82\x99","\xe3\x81\x90", //GU
"\xe3\x81\x91\xe3\x82\x99","\xe3\x81\x92", //GE
"\xe3\x81\x93\xe3\x82\x99","\xe3\x81\x94", //GO
"\xe3\x81\x95\xe3\x82\x99","\xe3\x81\x96", //ZA
"\xe3\x81\x97\xe3\x82\x99","\xe3\x81\x98", //ZI
"\xe3\x81\x99\xe3\x82\x99","\xe3\x81\x9a", //ZU
"\xe3\x81\x9b\xe3\x82\x99","\xe3\x81\x9c", //ZE
"\xe3\x81\x9d\xe3\x82\x99","\xe3\x81\x9e", //ZO
"\xe3\x81\x9f\xe3\x82\x99","\xe3\x81\xa0", //DA
"\xe3\x81\xa1\xe3\x82\x99","\xe3\x81\xa2", //DI
"\xe3\x81\xa4\xe3\x82\x99","\xe3\x81\xa5", //DU
"\xe3\x81\xa6\xe3\x82\x99","\xe3\x81\xa7", //DE
"\xe3\x81\xa8\xe3\x82\x99","\xe3\x81\xa9", //DO
"\xe3\x81\xaf\xe3\x82\x99","\xe3\x81\xb0", //BA
"\xe3\x81\xaf\xe3\x82\x9a","\xe3\x81\xb1", //PA
"\xe3\x81\xb2\xe3\x82\x99","\xe3\x81\xb3", //BI
"\xe3\x81\xb2\xe3\x82\x9a","\xe3\x81\xb4", //PI
"\xe3\x81\xb5\xe3\x82\x99","\xe3\x81\xb6", //BU
"\xe3\x81\xb5\xe3\x82\x9a","\xe3\x81\xb7", //PU
"\xe3\x81\xb8\xe3\x82\x99","\xe3\x81\xb9", //BE
"\xe3\x81\xb8\xe3\x82\x9a","\xe3\x81\xba", //PE
"\xe3\x81\xbb\xe3\x82\x99","\xe3\x81\xbc", //BO
"\xe3\x81\xbb\xe3\x82\x9a","\xe3\x81\xbd", //PO

"\xe3\x82\xab\xe3\x82\x99","\xe3\x82\xac", //GA
"\xe3\x82\xad\xe3\x82\x99","\xe3\x82\xae", //GI
"\xe3\x82\xaf\xe3\x82\x99","\xe3\x82\xb0", //GU
"\xe3\x82\xb1\xe3\x82\x99","\xe3\x82\xb2", //GE
"\xe3\x82\xb3\xe3\x82\x99","\xe3\x82\xb4", //GO
"\xe3\x82\xb5\xe3\x82\x99","\xe3\x82\xb6", //ZA
"\xe3\x82\xb7\xe3\x82\x99","\xe3\x82\xb8", //ZI
"\xe3\x82\xb9\xe3\x82\x99","\xe3\x82\xba", //ZU
"\xe3\x82\xbb\xe3\x82\x99","\xe3\x82\xbc", //ZE
"\xe3\x82\xbd\xe3\x82\x99","\xe3\x82\xbe", //ZO
"\xe3\x82\xbf\xe3\x82\x99","\xe3\x83\x80", //DA
"\xe3\x83\x81\xe3\x82\x99","\xe3\x83\x82", //DI
"\xe3\x83\x84\xe3\x82\x99","\xe3\x83\xa5", //DU
"\xe3\x83\x86\xe3\x82\x99","\xe3\x83\x87", //DE
"\xe3\x83\x88\xe3\x82\x99","\xe3\x83\x89", //DO
"\xe3\x83\x8f\xe3\x82\x99","\xe3\x83\x90", //BA
"\xe3\x83\x8f\xe3\x82\x9a","\xe3\x83\x91", //PA
"\xe3\x83\x92\xe3\x82\x99","\xe3\x83\x93", //BI
"\xe3\x83\x92\xe3\x82\x9a","\xe3\x83\x94", //PI
"\xe3\x83\x95\xe3\x82\x99","\xe3\x83\x96", //BU
"\xe3\x83\x95\xe3\x82\x9a","\xe3\x83\x97", //PU
"\xe3\x83\x98\xe3\x82\x99","\xe3\x83\x99", //BE
"\xe3\x83\x98\xe3\x82\x9a","\xe3\x83\x9a", //PE
"\xe3\x83\x9b\xe3\x82\x99","\xe3\x83\x9c", //BO
"\xe3\x83\x9b\xe3\x82\x9a","\xe3\x83\x9d", //PO
NULL,NULL,
};

#define UTF8_PREFIX 0xe3
#define UTF8_M_S_T1_FROM 0x80
#define UTF8_M_S_T1_TO   0x84
#define UTF8_M_S_T2_FROM 0x7f
#define UTF8_M_S_T2_TO   0xc0

#define UTF8_S_M_T1_FROM 0x80
#define UTF8_S_M_T1_TO   0x84
#define UTF8_S_M_T2_FROM 0x7f
#define UTF8_S_M_T2_TO   0xc0

char* macutf8_to_utf8(char* src){
  if (src == NULL){
    return 0;
  }
//printf("macutf8_to_utf8 #%s#\n",src);
  long slen = strlen(src)+1;
  char* dest = new char[slen];

  long sptr = 0;
  long dptr = 0;
  while(1){
    if (src[sptr] == 0){
      dest[dptr] = 0;
      return dest;
    }
    if ((unsigned char)src[sptr] == UTF8_PREFIX){
      if ((unsigned char)src[sptr+1] > UTF8_M_S_T1_FROM &&
          (unsigned char)src[sptr+1] < UTF8_M_S_T1_TO){
        if ((unsigned char)src[sptr+2] > UTF8_M_S_T2_FROM &&
            (unsigned char)src[sptr+2] < UTF8_M_S_T2_TO){
          long tblptr = 0;
          long converted = 0;
          while(1){
            if (cvt_table[tblptr*2] == NULL){
              break;
            }
            if (!strncmp(&src[sptr],
                         cvt_table[tblptr*2],
                         strlen(cvt_table[tblptr*2]))){
              converted = 1;
              strcpy(&dest[dptr],cvt_table[tblptr*2+1]);
//printf("macutf8_to_utf8 converted!! #%s#\n",dest);
              sptr += strlen(cvt_table[tblptr*2]);
              dptr += strlen(cvt_table[tblptr*2+1]);
              break;
            }
            tblptr++;
          }
          if(converted == 1){
            continue;
          }
        }
      }
    }
    dest[dptr] = src[sptr];
    sptr++;
    dptr++;
  }
  return dest;
}
char* utf8_to_macutf8(char* src){
  if (src == NULL){
    return 0;
  }
  long slen = strlen(src)+1;
  char* dest = new char[slen*2];

  long sptr = 0;
  long dptr = 0;
  while(1){
    if (src[sptr] == 0){
      dest[dptr] = 0;
      return dest;
    }
    if ((unsigned char)src[sptr] == UTF8_PREFIX){
      if ((unsigned char)src[sptr+1] > UTF8_S_M_T1_FROM &&
          (unsigned char)src[sptr+1] < UTF8_S_M_T1_TO){
        if ((unsigned char)src[sptr+2] > UTF8_S_M_T2_FROM &&
            (unsigned char)src[sptr+2] < UTF8_S_M_T2_TO){
          long tblptr = 0;
          long converted = 0;
          while(1){
            if (cvt_table[tblptr*2+1] == NULL){
              break;
            }
            if (!strncmp(&src[sptr],
                         cvt_table[tblptr*2+1],
                         strlen(cvt_table[tblptr*2+1]))){
              converted = 1;
              strcpy(&dest[dptr],cvt_table[tblptr*2]);
              sptr += strlen(cvt_table[tblptr*2+1]);
              dptr += strlen(cvt_table[tblptr*2]);
              break;
            }
            tblptr++;
          }
          if(converted == 1){
            continue;
          }
        }
      }
    }
    dest[dptr] = src[sptr];
    sptr++;
    dptr++;
  }
  return dest;
}

