/** 
 *  Yudit Unicode Editor Source File
 *
 *  GNU Copyright (C) 1997-2005  Gaspar Sinai <gsinai@yudit.org>  
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2,
 *  dated June 1991. See file COPYYING for details.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef USE_GETTEXT
extern "C"
{
#include <libintl.h>
}
#endif
#include <stdlib.h>

#include "gui/Main.h"
#include "gui/SYudit.h"

#include "stoolkit/SString.h"
#include "stoolkit/SStringVector.h"
#include "stoolkit/SProperties.h"
#include "stoolkit/SIO.h"
#include "stoolkit/SIOStream.h"
#include "stoolkit/SUniMap.h"
#include "stoolkit/SUtil.h"
#include "swindow/SFontImpl.h"

#include "swindow/SAwt.h"

#ifndef USE_WINAPI
#include <unistd.h> 
#include <pwd.h>
#include <sys/types.h>
#endif

int
main (int argc, char* argv[])
{
  /* have to set the path before awt */
  SUniMap::guessPath ();

  unsigned int i; unsigned int j;
  SString home = getHome();
  SString yuditdir = getPrefix();
  
  SString dotdir = home;
  dotdir.append ("/");
  dotdir.append (".yudit");
  SDir d (dotdir);
  if (!d.exists())
  {
    if (d.create())
    {
      fprintf (stderr, "yudit: created directory `%*.*s'\n",
         SSARGS (dotdir));
    }
    else
    {
      fprintf (stderr, "yudit: can not create directory `%*.*s'\n",
         SSARGS (dotdir));
      // don't exit on windows ! They won't know a thing.
      //exit (1);
    }
  }
  else if (!d.readable())
  {
    fprintf (stderr, "yudit: Can not read directory `%*.*s'\n",
        SSARGS (dotdir));
  }

  SString fontdir(dotdir);
  fontdir.append ("/");
  fontdir.append ("fonts");
  SDir dfont (fontdir);
  if (!dfont.exists())
  {
    dfont.create ();
  }
  SString dotdata(dotdir);
  dotdata.append ("/");
  dotdata.append ("data");
  SDir ddotdata (dotdata);
  if (!ddotdata.exists())
  {
    ddotdata.create ();
  }

  SStringVector args;
  SProperties   properties;

  

  /**
   *-----------------------------------------------------------------------
   * The default configuration section this will always be here.
   *-----------------------------------------------------------------------
   */
  //properties.put ("yudit.datapath", );
  //properties.put ("yudit.fontpath", );
  properties.put ("yudit.background", "gray50");
  properties.put ("yudit.label.foreground", "moccasin");
  properties.put ("yudit.title.foreground", "white");


  properties.put ("yudit.default.font", "default");
  properties.put ("yudit.default.fontsize", "16");
  properties.put ("yudit.default.geometry", "700x480");
  properties.put ("yudit.freehand.converter", "kanji");

  properties.put ("yudit.editor.background", "black");
  properties.put ("yudit.editor.left.foreground", "green");
  properties.put ("yudit.editor.right.foreground", "yellow");

  properties.put ("yudit.editor.caret.left.foreground", "red");
  properties.put ("yudit.editor.caret.right.foreground", "red");
  properties.put ("yudit.editor.showbreak", "true");

  /* enable syntax simple for people with old config file */
  properties.put ("yudit.editor.syntax", "simple");

  /* don't enable wordwrap for people with old config file */
  properties.put ("yudit.editor.wordwrap", "false");

  /* do over-the spot xim */
  properties.put ("yudit.editor.xinputs.style", "preedit-over-status-under");

  properties.put ("yudit.command.background", "black");
  properties.put ("yudit.command.left.foreground", "green");
  properties.put ("yudit.command.right.foreground", "yellow");
  properties.put ("yudit.command.caret.left.foreground", "red");
  properties.put ("yudit.command.caret.right.foreground", "red");
  properties.put ("yudit.slider.background", "#497986");
  properties.put ("yudit.editor.fontsizes", "10,12,14,16,24,48");
  properties.put ("yudit.editor.fonts", "default,TrueType,Bitmap");
#ifdef USE_WINAPI
  properties.put ("yudit.editor.inputs", 
    "straight,unicode,WindowsIM,Hungarian,Hangul,"
    "Kana,Mnemonic,Esperanto,Arabic,Hebrew,"
    "Russian,HungarianRunes");
#else
  properties.put ("yudit.editor.inputs", 
    "straight,unicode,kinput2,Hungarian,Hangul,"
    "Kana,Mnemonic,Esperanto,Arabic,Hebrew,"
    "Russian,HungarianRunes");
#endif
  if (isWinAPI())
  {
    properties.put ("yudit.editor.xinputs", "");
  }
  else
  {
    properties.put ("yudit.editor.xinputs", "utf-8:en_GB,utf-8:hu_HU,kinput2:ja_JP.eucJP,xcin:zh_TW.big5,Ami:ko_KR,xcin-zh_CN.GB2312:zh_CN.GB2312");
  }
  properties.put ("yudit.editor.fontsize", "16");
  properties.put ("yudit.editor.font", "default");
  properties.put ("yudit.editor.input", "straight");
  properties.put ("yudit.fonts", "default,TrueType,Bitmap");
  properties.put ("yudit.font.TrueType", 
       "arial.ttf,msgothic.ttf,gulim.ttf,"
       "-*-*-*-*-*--*-*-*-*-*-*-iso8859-1,"
       "cyberbit.ttf,yudit.ttf:cp-1250");

  properties.put ("yudit.font.Bitmap", 
   "-gnu-unifont-medium-r-normal--16-160-75-75-c-80-iso10646-1,*-iso8859-1,"
   "jisx0208.1983-0,"
   "jisx0201.1976-0,"
   "-sony-fixed-medium-r-normal--*-230-75-75-c-120-iso8859-1");

  properties.put ("yudit.default.printer.options", "");
  properties.put ("yudit.default.preview.command", "gv");

  /**
   * override everything with system prop 
   */
  SString yuditconfig(yuditdir);
  yuditconfig.append ("/config/yudit.properties");
  if (!loadProperties (yuditconfig, &properties))
  {
    fprintf (stderr, "could not load `%*.*s'.\n", SSARGS(yuditconfig));
  }
  else
  {
    //fprintf (stderr, "loaded `%*.*s'.\n", SSARGS(yuditconfig));
  }

  /**
   * User defined properties 
   */
  SProperties userProperties;
  userProperties.put ("yudit.default.clipboard.encoding", "iso-2022-x11");
  userProperties.put ("yudit.default.filetype", "utf-8");

  SString userconfig (dotdir);
  userconfig.append ("/yudit.properties");
  bool firsttime = false;
  if (!loadProperties (userconfig, &userProperties))
  {
    firsttime = true;
    //fprintf (stderr, "could not load `%*.*s'(not an error).\n", 
    //       SSARGS(userconfig));
  }
  else
  {
    //fprintf (stderr, "loaded `%*.*s'.\n", SSARGS(userconfig));
    const SString *str = userProperties.get ("yudit.default.preview.command");
    /* compatibility. remove this. */
    if (str!=0)
    { 
      const SString& ustr = *str;
      if (ustr.size() > 0 && ustr[0] == '-' && ustr[1] == 'e')
      {
         const SString& gvle = properties["yudit.default.preview.command"];
         fprintf (stderr, "moving yudit.default.preview.command '%*.*s' to '%*.*s' (compatibility 2.5).\n", 
           SSARGS(ustr), SSARGS(gvle));
         fprintf (stderr, "To get rid of this message set your yudit.default.preview.command in %*.*s (like: gv).\n", 
           SSARGS (userconfig));
         userProperties.put ("yudit.default.preview.command", SString(gvle));
      }
    }
  }
  
  SProperties allProperties(properties);
  userProperties.remove ("00HEADER.#");
  userProperties.remove ("yudit.default.language.#");
  allProperties.merge (userProperties);
  if (allProperties.get ("yudit.default.file")==0)
  {
    allProperties.put ("yudit.default.file", "untitled.utf8");
  }

  /* you can not override this */
  allProperties.put ("yudit.config", userconfig);
  SStringVector ve(allProperties["yudit.editor.fonts"]);
  SStringVector vy(allProperties["yudit.fonts"]);

  for (i=0; i<ve.size(); i++)
  {
    for (j=0; j<vy.size(); j++)
    {
       if (vy[j] == ve[i]) break;
    }
    if (j == vy.size()) vy.append (ve[i]);
  }

  /**
   * Check if all fonts are defined.
   */
  SProperties fontProps;
  for (i=0; i<vy.size(); )
  {
    if (vy[i] == "default")
    {
      i++;
      continue;
    }
    SString str("yudit.font.");
    str.append (vy[i]);
    if (!allProperties.get (str))

    {
      fprintf (stderr, "removing: '%*.*s' from list - not defined.\n", SSARGS(str));
      //fprintf (stderr, "ALL=\n%*.*s\n", SSARGS(allProperties.toString()));
      vy.remove(i);
      i=0;
    }
    else
    {
      fontProps.put (vy[i], allProperties[str]);
      i++;
    }
  }

  SAwt awt;
  if (!awt.implemented())
  {
    fprintf (stderr, "AWT is not implemented on this platform.\n");
    return 0;
  }

  /* have to set the path after first awt */
  SFontImpl::guessPath ();
  SString clipEnc = allProperties["yudit.default.clipboard.encoding"];
  if (clipEnc.size())
  {
    awt.setEncoding (clipEnc);
//SStringVector all = SUniMap::getPath();
//SString s = all.join (",");
//fprintf (stderr, "setting clipboard encoder to %*.*s\n", SSARGS(clipEnc));
  }

  /* init fonts */
  for (i=0; i< vy.size(); i++)
  {
    SString key = vy[i];
    if (key == "default") continue;
    SString str = fontProps[key];
    SStringVector curr(str);
    
    SFontImplVector list;
    for (j=0; j<curr.size(); j++)
    {
      /* encoding is optional */
      SStringVector v(curr[j], ":");
      SString enc = v[0];
      if (v.size()>1 && v[1].size()!=0) enc = v[1];
      SFontImpl impl (v[0], enc);

      if (v.size()>2 && v[2].size()>0)
      {
         SStringVector pvect(v[2], ";");
         SProperties props;
         for (unsigned int j=0; j<pvect.size(); j++)
         {
            SStringVector vv(pvect[j], "=", true);
            if (vv.size() > 1)
            {
               props.put (vv[0], vv[1]);
            }
            else
            {
               props.put (vv[0], "true");
            }
         }
         impl.setAttributes(props);
      }
      list.append (impl);
    }
    //fprintf (stderr, "initializing %*.*s\n", SSARGS(key));
    SFont::put (key, list);
  }

  int k; 
  for (k=0; k<argc; k++)
  {
    args.append (argv[k]);
  }
  if (argc==1 && firsttime)
  {
    args.append ("-help");
  }
  SString ldir (yuditdir);
  ldir.append ("/locale");
  initTranslate ("messages", ldir);
  if (allProperties.get ("yudit.default.language"))
  {
    SString lang = allProperties["yudit.default.language"];
    lang.replaceAll(" ", "");
    if (lang.size()>0 && lang!=SString("default"))
    {
       /* no spaces */
       setLanguage (lang);
    }
    else if (lang==SString("default"))
    {
      setLanguage (getSystemLanguage ("en"));
    }
  }
  SYudit *yudit = new SYudit (args, allProperties);
#ifdef USE_WINAPI
  /* they have no concept of window managers */
  yudit->center();
#endif
  yudit->show();
  SEventHandler::start();
  return 0;
}

