/***************************************************************************
                          gui.cpp  -  description
                             -------------------
    begin                : 06.08.02
    copyright            : (C) 2002-2009 by Andre Simon
    email                : andre.simon1@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/


#include "gui.h"
#include <memory>

#include <wx/version.h>
#include <wx/stdpaths.h>
#include <wx/filefn.h>
#include <wx/ffile.h>
#include <wx/fileconf.h>
#include <wx/clipbrd.h>
#include <wx/fontdlg.h>

#include "gui_failure_dlg.h"
#include "gui_showfile_dlg.h"
#include "highlight.xpm"

#define MAX_LINE__WIDTH       80

using namespace std;

// Main Application

bool HighlightApp::OnInit()
{
   const wxCmdLineEntryDesc cmdLineDesc[] ={
    { wxCMD_LINE_PARAM,  NULL, NULL, "input file", wxCMD_LINE_VAL_STRING,
        wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL },
    { wxCMD_LINE_OPTION, "u", "user-profile",  "user profile directory",
        wxCMD_LINE_VAL_STRING,
        wxCMD_LINE_PARAM_OPTIONAL },
    {wxCMD_LINE_NONE}
   };

   wxCmdLineParser parser(argc, argv);
   parser.SetDesc(cmdLineDesc);
   parser.Parse();

   HighlightFrame *win = new HighlightFrame(HIGHLIGHT_VERSION2);

   wxString userProfileDir;
   if (parser.Found(("user-profile"), &userProfileDir)){
        win->setUserProfilePath(userProfileDir.c_str());
   } else {
        win->setUserProfilePath(wxStandardPathsBase::Get().GetUserDataDir().c_str());
   }

   win->initInterface();

   if (win->getFatalError()) return false;

   if (parser.GetParamCount()){
     wxArrayString inputFileList;
     for (unsigned int i=0;i<parser.GetParamCount();i++){
       inputFileList.Add(parser.GetParam(i));
     }
     win->addInputFiles(inputFileList, "", true);
   }
   win->Show(true);
   SetTopWindow(win);
   win->showStartupTips();

   /* Do not return FALSE or the app will terminate immediately */
   return true;
}

void HighlightFrame::setUserProfilePath(const char* path){
      userPrefBaseDir=string(path);
}

// Main Window
HighlightFrame::HighlightFrame(const wxString &title)
    : wxFrame((wxFrame *) NULL, -1, title, wxDefaultPosition, wxDefaultSize,
               wxDEFAULT_FRAME_STYLE),
     styleOutFileName(NULL),
     language(("English")),
     lastOutType(highlight::HTML),
     fcStrings(NULL)
{
	dataDir.searchDataDir("");
}

void HighlightFrame::initInterface(){

   preferencesPath=userPrefBaseDir+Platform::pathSeparator+"highlight.conf";
   defaultProjectPath=userPrefBaseDir+Platform::pathSeparator+"highlight.hpr";

   currentProjectPath=defaultProjectPath;

   wxString lastProject;
   wxFileConfig projectConfig ("Highlight", wxEmptyString, preferencesPath,
                                wxEmptyString,
                                wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_NO_ESCAPE_CHARACTERS);
   projectConfig.Read("language",&language, ("English"));
   projectConfig.Read("showTips",&showTips, true);
   projectConfig.Read("lastTip",&lastTip, 1);
   projectConfig.Read("lastProject",&lastProject,"");

   int x=0, y=0, width=0, height=0;
   projectConfig.Read(("winXPos"),&x, 0);
   projectConfig.Read(("winYPos"),&y, 0);
   projectConfig.Read(("winWidth"),&width, 0);
   projectConfig.Read(("winHeight"),&height, 0);

   if (!lastProject.empty() && lastProject != defaultProjectPath)
          currentProjectPath=lastProject;

   fatalError=!loadLanguage(language);

   SetIcon(wxIcon(highlight_xpm));

   menuFile = new wxMenu(),
   menuHelp = new wxMenu();
   menuLang = new wxMenu();
   menuPrj = new wxMenu();

   MenuBar = new wxMenuBar();
   menuFile->Append(ID_MENU_OPENFILES,fcStrings->Read(("m001"), wxEmptyString));
   menuFile->AppendSeparator();
   menuFile->Append(PROGRAM_QUIT,fcStrings->Read(("m002"), wxEmptyString));
   menuHelp->Append(ID_MENU_HELP, fcStrings->Read(("m003"), wxEmptyString));
   menuHelp->Append(ID_MENU_TIPS, fcStrings->Read(("m009"), wxEmptyString));
   menuHelp->AppendSeparator();
   menuHelp->Append(ID_MENU_LICENSE, fcStrings->Read(("m004"), wxEmptyString));
   menuHelp->Append(ID_MENU_CHANGELOG, fcStrings->Read(("m005"), wxEmptyString));
   menuHelp->AppendSeparator();
   menuHelp->Append(ID_MENU_ABOUT, fcStrings->Read(("m006"), wxEmptyString));
   menuPrj->Append(ID_MENU_PRJ_LOAD, fcStrings->Read(("m011"), wxEmptyString));
   menuPrj->Append(ID_MENU_PRJ_SAVE, fcStrings->Read(("m012"), wxEmptyString));
   menuPrj->AppendSeparator();
   menuPrj->Append(ID_MENU_PRJ_LOAD_DEF, fcStrings->Read(("m013"), wxEmptyString));

   wxFileName i18nFileName;
   wxArrayString i18nFiles;
   wxDir::GetAllFiles(wxString(dataDir.getI18nDir().c_str()),
                      &i18nFiles, wxString(("*.txt")), (int)wxDIR_FILES);
   i18nFiles.Sort();
   if ( i18nFiles.IsEmpty()) {
       wxMessageBox(wxString(("i18n folder not found. Check installation.")),
                    wxString(("Error.")),
                    wxICON_EXCLAMATION);
       return;
   }
   // apart from English.txt, more translation files exist
   bool translationsAvailable=i18nFiles.GetCount()>1;
   if (translationsAvailable){
     for (unsigned int i=0; i<i18nFiles.GetCount(); i++){
       Connect(ID_MENU_LANGUAGE_DYN + i,  -1, wxEVT_COMMAND_MENU_SELECTED,
               (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
               &HighlightFrame::OnCheckLanguage);
       i18nFileName.Assign(wxString(i18nFiles[i].c_str()));
       menuLang->AppendRadioItem(ID_MENU_LANGUAGE_DYN + i, i18nFileName.GetName());
     }
     menuLang->Check(menuLang->FindItem(wxString(language.c_str())), true);
  }

   MenuBar->Append(menuFile, fcStrings->Read(("m007"), wxEmptyString));
   MenuBar->Append(menuPrj, fcStrings->Read(("m010"), wxEmptyString));
   MenuBar->Append(menuLang, fcStrings->Read(("m008"), wxEmptyString));
   MenuBar->Append(menuHelp, fcStrings->Read(("m003"), wxEmptyString));

   SetMenuBar(MenuBar);
   MenuBar->EnableTop(1, translationsAvailable);

   panel =new wxPanel(this, ID_PANEL);
   butSource = new wxButton(panel, ID_BUTTON_OPENFILES,
                            fcStrings->Read(("l001"), wxEmptyString),
                            wxDefaultPosition, wxDefaultSize, 0 );

   listBox = new wxListBox(panel, ID_LISTBOX, wxDefaultPosition,
                           wxSize(200,150), 0, NULL,
                           wxLB_NEEDED_SB |wxLB_EXTENDED | wxLB_HSCROLL);

   butRemoveSelection=new wxButton(panel, ID_BUTTON_REMOVE,
                                    fcStrings->Read(("l033"), wxEmptyString),
                                    wxDefaultPosition, wxDefaultSize, 0 );

   butClearList = new wxButton(panel, ID_BUTTON_CLEAR,
                                    fcStrings->Read(("l003"), wxEmptyString),
                                    wxDefaultPosition, wxDefaultSize, 0 );

   // Spanish out directory label is very long, split in 2 lines
   wxString outDirLbl=wxString::Format(fcStrings->Read("l002", wxEmptyString),"\n");
   lblOutDir = new wxStaticText(panel, -1, outDirLbl);

   outDir = new  wxTextCtrl(panel, ID_OUTDIRTEXT, "");

   butOutDir = new wxButton( panel, ID_BUTTON_OUTDIR,( "...") , wxDefaultPosition,
                             wxSize(25,-1), 0 );

   writeToSourceDir= new wxCheckBox(panel, ID_WRITE_TO_SRCDIR,
                                 fcStrings->Read(("l032"), wxEmptyString));

   lblOutputFormat = new wxStaticText(panel, -1, fcStrings->Read(("l004"),
                                      wxEmptyString));

   wxString formatNames[] = {"HTML","XHTML", "LaTeX","TeX", "RTF", "SVG", "XML"};
   outputFormatChoice=new wxChoice(panel, ID_FORMAT_CHOICE, wxDefaultPosition,
                      wxDefaultSize, wxArrayString(NUMBER_FORMATS, formatNames));
   outputFormatChoice->SetSelection(0);

   linenumbers = new wxCheckBox(panel, ID_INCLUDELINENUMBERS,
                                fcStrings->Read(("l013"), wxEmptyString));

   attachAnchors= new wxCheckBox(panel, ID_ATTACHANCHORS,
                                 fcStrings->Read(("l006"), wxEmptyString));

   useFileAsAnchorName= new wxCheckBox(panel, ID_USEFILEASANCHORNAME,
                                 fcStrings->Read(("l042"), wxEmptyString));


   orderedList= new wxCheckBox(panel, ID_ORDERED_LIST,
                                 fcStrings->Read(("l037"), wxEmptyString));

   lnFillZeroes = new wxCheckBox(panel, ID_FILL_ZEROES,
                                 fcStrings->Read(("l031"), wxEmptyString));

   wrapLines= new wxCheckBox(panel, ID_WRAP,
                                 fcStrings->Read(("l027"), wxEmptyString));

   wrapLinesIntelligent= new wxCheckBox(panel, ID_WRAP_CAUTIOUS,
                                 fcStrings->Read(("l028"), wxEmptyString));

   fragment = new wxCheckBox(panel, ID_FRAGMENT,
                             fcStrings->Read(("l014"), wxEmptyString));

   enclosePreTag = new wxCheckBox(panel, ID_ENCLOSEPRETAG,
                             fcStrings->Read(("l050"), "Enclose in <pre>"));

   includeStyle = new wxCheckBox(panel, ID_INCLUDECSS,
                               fcStrings->Read(("l005"), wxEmptyString));
   inlineCSS = new wxCheckBox(panel, ID_INLINECSS,
                               fcStrings->Read(("l048"), "Inline CSS"));

   generateHtmlIndex=new wxCheckBox(panel, ID_GENERATEINDEX,
                                    fcStrings->Read(("l008"), wxEmptyString));

   replaceLatexQuotes=new wxCheckBox(panel, ID_REPLACE_QUOTES,
                                    fcStrings->Read(("l029"), wxEmptyString));
   enableLaTeXBabelCompat=new wxCheckBox(panel, ID_BABEL_COMPAT,
                                    fcStrings->Read(("l038"), wxEmptyString));

   lblColourTheme= new wxStaticText(panel, -1, fcStrings->Read(("l010"), wxEmptyString));

   themeChoice=new wxChoice(panel, ID_THEMECHOICE, wxDefaultPosition,
                             wxSize(100,-1), 0, 0, wxCB_SORT);

   reformatCode= new wxCheckBox(panel, ID_REFORMATCODE,
                                fcStrings->Read(("l007"), wxEmptyString));

    changeCase= new wxCheckBox(panel, ID_CHANGECASE,
                               fcStrings->Read(("l047"), wxEmptyString));

   reformatChoice=new wxChoice(panel, ID_REFORMATCHOICE, wxDefaultPosition,
                             wxSize(100,-1), 0, 0, wxCB_SORT);


   lblTabWidth=new wxStaticText(panel, ID_TAB_WIDTH, fcStrings->Read(("l030"), wxEmptyString));
   tabWidth= new wxSpinCtrl(panel, ID_TAB_WIDTH,("4"), wxDefaultPosition,
                            wxSize(60,-1), wxSP_ARROW_KEYS, 0, 8 , 4);

   lblLineLength=new wxStaticText(panel, ID_LINE_LEN, fcStrings->Read(("l046"), wxEmptyString));
   lineLength= new wxSpinCtrl(panel, ID_LINE_LEN,("80"), wxDefaultPosition,
                            wxSize(60,-1), wxSP_ARROW_KEYS, 60, 160, 80 );

   useEncoding= new wxCheckBox(panel, ID_USE_ENCODING,
                                fcStrings->Read(("l036"), wxEmptyString));

   wxString encodingNames[] = { ("ISO-8859-1"), ("ISO-8859-2"), ("ISO-8859-3"),
                                ("ISO-8859-4"), ("ISO-8859-5"), ("ISO-8859-6"),
                                ("ISO-8859-7"), ("ISO-8859-8"), ("ISO-8859-9"),
                                ("ISO-8859-10"), ("ISO-8859-11"), ("ISO-8859-13"),
                                ("ISO-8859-14"), ("ISO-8859-15"), ("UTF-8")};

   encodingChoice=new wxComboBox(panel, ID_ENCODING_LIST, (""), wxDefaultPosition,
                                 wxSize(100,-1),
                                 wxArrayString (NUMBER_ENCODINGS, encodingNames),
                                 wxCB_DROPDOWN );
   encodingChoice->SetSelection(0);

   wxString caseNames[] = { ("UPPER"), ("lower"),("Capitalize") };
   caseChoice=new wxChoice(panel, ID_CASECHOICE, wxDefaultPosition,
                                 wxSize(100,-1),
                                 wxArrayString (3, caseNames));
   caseChoice->SetSelection(0);

   lblPageSize= new wxStaticText(panel, -1, fcStrings->Read(("l039"), wxEmptyString));
   wxString pageSizes[] = {("A3"),("A4"),("A5"),("B4"), ("B5"), ("B6"),
   ("Letter"), ("Legal")};
   pageSizeChoice=new wxChoice(panel, ID_FORMAT_CHOICE, wxDefaultPosition,
                            wxSize(100,-1), wxArrayString(8, pageSizes));
   pageSizeChoice->SetSelection(1);

   cbRTFAddCharStyles= new wxCheckBox(panel, ID_ADD_CHAR_STYLES,
                                 fcStrings->Read(("l056"), "RTF character styles"));

   useTagsInfo= new wxCheckBox(panel, ID_READ_TAGS,
                                 fcStrings->Read(("l057"), "Read Tags File"));
   tagsPath = new wxTextCtrl(panel, ID_TAGS_INFILE ,"",wxDefaultPosition, wxSize(75,-1));
   btTagsInFile= new wxButton( panel, ID_BUTTON_OPEN_TAGS_INFILE, "...",
                                     wxDefaultPosition,  wxSize(25,-1), 0);

   wxString str=wxString::Format("%s %s", fcStrings->Read("l011", wxEmptyString).c_str(),
                   ((styleOutFileName!=NULL)?(styleOutFileName->GetValue()).c_str():
                      (CSS_DEFAULT_NAME)));

   lblStyleIn= new wxStaticText(panel, -1,str);
   styleInFileName = new wxTextCtrl(panel, ID_CSS_INFILE);
   butChooseStyleInfile = new wxButton( panel, ID_BUTTON_OPEN_CSS_INFILE, "...",
                                     wxDefaultPosition,  wxSize(25,-1), 0);

   lblStyleOut= new wxStaticText(panel, -1, fcStrings->Read("l009", wxEmptyString));

   styleOutFileName = new wxTextCtrl(panel, ID_CSS_OUTFILE, CSS_DEFAULT_NAME);

   butStart = new wxButton(panel, ID_START, fcStrings->Read("l015", wxEmptyString),
                           wxDefaultPosition, wxDefaultSize, 0 );
   butStart->SetFont(wxFont(11, wxDEFAULT , wxNORMAL,wxBOLD));

   butClipboard = new wxButton(panel, ID_CLIPBRD, fcStrings->Read("l049", "Clipboard"),
                           wxDefaultPosition, wxDefaultSize, 0 );

   progress= new wxGauge(panel, ID_PROGRESS, 100, wxDefaultPosition,
                         wxDefaultSize,wxGA_SMOOTH );

   lblSVGSize= new wxStaticText(panel, -1,  fcStrings->Read("l051", "SVG size:") );
   svgWidth = new wxTextCtrl(panel, -1, "",wxDefaultPosition,  wxSize(45,-1));
   svgHeight = new wxTextCtrl(panel, -1, "",wxDefaultPosition,  wxSize(45,-1));

   cbCustomFont = new wxCheckBox(panel, ID_USERFONT,
                                 fcStrings->Read("l052", "Apply Custom Font")) ;
   lblFontFace = new wxStaticText(panel, -1, fcStrings->Read("l053", "Font face:"));
   fontFace = new wxTextCtrl(panel, -1, "Courier New", wxDefaultPosition, wxSize(100,-1));
   lblFontSize = new wxStaticText(panel, -1, fcStrings->Read("l055", "Font size:"));
   fontSize = new  wxTextCtrl(panel, -1, "10", wxDefaultPosition, wxSize(50,-1));
   btFontDlg = new wxButton( panel, ID_BUTTON_FONTDLG, fcStrings->Read("l054", "Font..."),
                             wxDefaultPosition,wxSize(100,-1));

  // Layout ***************************************************************

   wxBoxSizer *leftsizer = new wxBoxSizer( wxVERTICAL );
   leftsizer->Add(butSource, 0, wxTOP | wxGROW | wxALIGN_CENTER_HORIZONTAL, 5 );
   leftsizer->Add(
    listBox,
    1,            // make vertically stretchable
    wxGROW |    // make horizontally stretchable
    wxTOP|wxBOTTOM,        //   and make border all around
    10 );         // set border width to 10

  leftsizer->Add( butRemoveSelection, 0, wxTOP | wxGROW | wxALIGN_CENTER_HORIZONTAL, 5 );
  leftsizer->Add(butClearList, 0, wxTOP | wxGROW | wxALIGN_CENTER_HORIZONTAL, 5 );

   wxStaticBox *outDirBox= new wxStaticBox(panel, -1, ("") );
   wxStaticBoxSizer *outDirBoxSizer = new wxStaticBoxSizer( outDirBox, wxVERTICAL );
   wxBoxSizer* outDirSelSizer = new wxBoxSizer(wxHORIZONTAL);
   outDirSelSizer->Add( outDir, 1, wxALIGN_CENTRE|wxALL|wxGROW , 5 );
   outDirSelSizer->Add( butOutDir, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 0 );
   outDirBoxSizer->Add( lblOutDir, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2 );
   outDirBoxSizer->Add( outDirSelSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM|wxGROW, 5);
   outDirBoxSizer->Add( writeToSourceDir, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 5);
   leftsizer->Add(outDirBoxSizer,0, wxALIGN_CENTER_HORIZONTAL | wxTOP |wxGROW  | wxBOTTOM, 5);

    middlesizer = new wxBoxSizer( wxVERTICAL );

    wxStaticBox *formatChoiceBox= new wxStaticBox(panel, -1, (""));
    wxStaticBoxSizer *formatChoiceBoxSizer = new wxStaticBoxSizer( formatChoiceBox, wxVERTICAL );

    wxBoxSizer *formatSizer = new wxBoxSizer(wxHORIZONTAL );
    formatSizer->Add( lblOutputFormat, 0,  wxTOP | wxALIGN_CENTER_VERTICAL , 3 );
    formatSizer->Add(5, 0, 1);
    formatSizer->Add( outputFormatChoice, 0,  wxTOP , 5 );
    formatChoiceBoxSizer->Add( formatSizer, 0,  wxTOP| wxBOTTOM |wxGROW );

    middlesizer->Add(formatChoiceBoxSizer,0, wxGROW|wxTOP, 0);

    wxStaticBox *optBox= new wxStaticBox(panel, -1,"");
    wxStaticBoxSizer *optBoxSizer = new wxStaticBoxSizer( optBox, wxVERTICAL );
    optBoxSizer->Add(0, 5, 1);
    optBoxSizer->Add(linenumbers, 0, wxALIGN_LEFT );

    optBoxSizer->Add( attachAnchors, 0, wxALIGN_LEFT | wxLEFT | wxTOP, 5 );
    optBoxSizer->Add( useFileAsAnchorName, 0, wxALIGN_LEFT | wxLEFT| wxTOP, 5 );
    optBoxSizer->Add( orderedList, 0, wxALIGN_LEFT | wxLEFT| wxTOP, 5 );
    optBoxSizer->Add( lnFillZeroes, 0,  wxALIGN_LEFT | wxLEFT| wxTOP, 5 );
    optBoxSizer->Add( wrapLines, 0,   wxALIGN_LEFT | wxTOP, 5);
    optBoxSizer->Add( wrapLinesIntelligent, 0,  wxALIGN_LEFT | wxLEFT| wxTOP, 5);
    optBoxSizer->Add( fragment, 0, wxALIGN_LEFT| wxTOP, 5 );
    optBoxSizer->Add( enclosePreTag, 0,  wxALIGN_LEFT | wxLEFT| wxTOP, 5 );
    optBoxSizer->Add( includeStyle, 0,  wxALIGN_LEFT| wxTOP, 5);
    optBoxSizer->Add( inlineCSS, 0, wxALIGN_LEFT | wxLEFT| wxTOP, 5 );
    optBoxSizer->Add( generateHtmlIndex, 0,  wxALIGN_LEFT| wxTOP, 5 );
    optBoxSizer->Add( replaceLatexQuotes, 0, wxALIGN_LEFT| wxTOP, 5);
    optBoxSizer->Add( enableLaTeXBabelCompat, 0, wxALIGN_LEFT| wxTOP, 5 );
    optBoxSizer->Add( cbRTFAddCharStyles, 0, wxALIGN_LEFT| wxTOP, 5 );
    optBoxSizer->AddSpacer(5);
    middlesizer->Add(optBoxSizer,0, wxGROW);

    wxStaticBox *fontBox= new wxStaticBox(panel, -1, "");
    wxStaticBoxSizer *fontBoxSizer = new wxStaticBoxSizer( fontBox, wxVERTICAL );
    wxBoxSizer *fontSelectSizer = new wxBoxSizer(wxHORIZONTAL );
    wxBoxSizer *fontFaceSizer = new wxBoxSizer(wxHORIZONTAL );
    wxBoxSizer *fontSizeSizer = new wxBoxSizer(wxHORIZONTAL );

    fontSelectSizer->Add(cbCustomFont, 0, wxTOP|wxALIGN_CENTER_VERTICAL, 5);
    fontSelectSizer->Add(5, 0, 1);
    fontSelectSizer->Add(btFontDlg, 0, wxTOP);

    fontFaceSizer->Add(lblFontFace, wxALIGN_CENTER_VERTICAL);
    fontFaceSizer->Add(5, 0, 1);
    fontFaceSizer->Add(fontFace);
    fontSizeSizer->Add(lblFontSize, wxALIGN_CENTER_VERTICAL );
    fontSizeSizer->Add(5, 0, 1);
    fontSizeSizer->Add(fontSize);

    fontBoxSizer->Add(fontSelectSizer, 0, wxGROW|wxTOP, 5);
    fontBoxSizer->Add(fontFaceSizer, 0,wxGROW|wxTOP, 5);
    fontBoxSizer->Add(fontSizeSizer, 0,wxGROW|wxTOP, 5);
    middlesizer->Add(fontBoxSizer,0, wxBOTTOM|wxGROW, 5);

    wxStaticBox *choicesBox= new wxStaticBox(panel, -1, "");
    wxStaticBoxSizer *choicesBoxSizer = new wxStaticBoxSizer( choicesBox, wxVERTICAL );

    wxBoxSizer *themeSizer = new wxBoxSizer(wxHORIZONTAL );
    themeSizer->Add( lblColourTheme, 0,  wxTOP | wxALIGN_CENTER_VERTICAL , 3 );
    themeSizer->Add(5, 0, 1);
    themeSizer->Add( themeChoice, 0,  wxTOP , 5 );
    choicesBoxSizer->Add( themeSizer, 0, wxBOTTOM |wxGROW );

    wxBoxSizer *reformatSizer = new wxBoxSizer(wxHORIZONTAL );
    reformatSizer->Add(reformatCode,0, wxTOP | wxALIGN_CENTER_VERTICAL, 5);
    reformatSizer->Add(5, 0, 1);
    reformatSizer->Add(reformatChoice,0, wxTOP, 5);
    choicesBoxSizer->Add( reformatSizer, 0, wxGROW);

    wxBoxSizer *caseSizer = new wxBoxSizer(wxHORIZONTAL );
    caseSizer->Add(changeCase,0, wxTOP | wxALIGN_CENTER_VERTICAL, 5);
    caseSizer->Add(5, 0, 1);
    caseSizer->Add(caseChoice,0, wxTOP, 5);
    choicesBoxSizer->Add( caseSizer, 0, wxGROW);

    wxBoxSizer *tabSizer = new wxBoxSizer(wxHORIZONTAL );
    tabSizer->Add(lblTabWidth, 0, wxTOP|wxALIGN_CENTER_VERTICAL , 5);
    tabSizer->Add(5, 0, 1);
    tabSizer->Add(tabWidth, 0, wxTOP, 3);
    wxBoxSizer *lenSizer = new wxBoxSizer(wxHORIZONTAL );
    lenSizer->Add(lblLineLength, 0, wxTOP|wxALIGN_CENTER_VERTICAL , 5);
    lenSizer->Add(5, 0, 1);
    lenSizer->Add(lineLength, 0, wxTOP, 3);
    choicesBoxSizer->Add( tabSizer, 0, wxTOP| wxBOTTOM| wxGROW);
    choicesBoxSizer->Add( lenSizer, 0, wxTOP| wxBOTTOM| wxGROW);

    wxBoxSizer *encodingSizer = new wxBoxSizer(wxHORIZONTAL );
    encodingSizer->Add(useEncoding,0, wxTOP | wxALIGN_CENTER_VERTICAL, 5);
    encodingSizer->Add(5, 0, 1);
    encodingSizer->Add(encodingChoice,0, wxTOP, 5);
    choicesBoxSizer->Add( encodingSizer, 0,  wxTOP |wxGROW );


   wxBoxSizer *tagsSizer = new wxBoxSizer(wxHORIZONTAL );
    tagsSizer->Add(useTagsInfo,0, wxTOP | wxALIGN_CENTER_VERTICAL, 5);
    tagsSizer->Add(5, 0, 1);
    tagsSizer->Add(tagsPath,0, wxTOP, 5);
    tagsSizer->Add(btTagsInFile,0, wxTOP, 5);
    choicesBoxSizer->Add( tagsSizer, 0,  wxTOP |wxGROW );


    wxBoxSizer *pageSizeSizer = new wxBoxSizer(wxHORIZONTAL );
    pageSizeSizer->Add( lblPageSize, 0,  wxTOP | wxALIGN_CENTER_VERTICAL , 3 );
    pageSizeSizer->Add(5, 0, 1);
    pageSizeSizer->Add( pageSizeChoice, 0, wxTOP , 5 );
    choicesBoxSizer->Add( pageSizeSizer, 0, wxTOP| wxBOTTOM |wxGROW );

    lblSVGx= new wxStaticText(panel, -1, "x");
    wxBoxSizer *svgSizeSizer = new wxBoxSizer(wxHORIZONTAL );
    svgSizeSizer->Add(lblSVGSize, 0, wxTOP | wxALIGN_CENTER_VERTICAL, 3 );
    svgSizeSizer->Add(5, 0, 1);
    svgSizeSizer->Add(svgWidth, 0, wxTOP, 5 );
    svgSizeSizer->Add(2, 0);
    svgSizeSizer->Add(lblSVGx, 0, wxTOP|wxALIGN_CENTER_VERTICAL, 5 );
    svgSizeSizer->Add(2, 0);
    svgSizeSizer->Add(svgHeight, 0, wxTOP, 5);
    choicesBoxSizer->Add(svgSizeSizer, 0, wxTOP|wxBOTTOM|wxGROW );

    middlesizer->Add(choicesBoxSizer,0, wxGROW);

    wxStaticBox *styleOptBox= new wxStaticBox(panel, -1, "");
    wxStaticBoxSizer *styleOptBoxSizer = new wxStaticBoxSizer( styleOptBox, wxVERTICAL );
    styleOptBoxSizer->Add( lblStyleOut, 0, wxTOP, 3 );
    styleOptBoxSizer->Add( styleOutFileName, 0,  wxGROW | wxALIGN_LEFT);
    styleOptBoxSizer->Add( lblStyleIn, 0,  wxTOP | wxALIGN_LEFT, 10 );
    wxBoxSizer *styleInSizer = new wxBoxSizer(wxHORIZONTAL );
    styleInSizer->Add( styleInFileName, 1,   wxALIGN_LEFT );
    styleInSizer->Add( butChooseStyleInfile, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL);
    styleOptBoxSizer->Add( styleInSizer, 0,wxGROW, 5);
    middlesizer->Add(styleOptBoxSizer,0, wxBOTTOM|wxGROW, 5);

   // middlesizer->Add(0, 20, 1);

    wxBoxSizer *previewsizer = new wxBoxSizer( wxVERTICAL );
    wxString pvLblText ;
    pvLblText.Printf(fcStrings->Read("l043", wxEmptyString).c_str(),
                                     fcStrings->Read("l045", wxEmptyString).c_str());
    lblPreview= new wxStaticText(panel, -1,  pvLblText);
    previewsizer->Add( lblPreview, 0,  wxTOP, 10 );
    preview = new wxHtmlWindow(panel, wxID_ANY,wxDefaultPosition,wxSize(250, 200),
                               wxHW_NO_SELECTION|wxHW_SCROLLBAR_AUTO);
    previewsizer->Add( preview, 1,  wxTOP | wxGROW , 10 );

    wxBoxSizer *convertsizer = new wxBoxSizer( wxHORIZONTAL );
    convertsizer->Add(butStart, 0,  wxTOP, 5 );
    convertsizer->Add(butClipboard, 0,  wxTOP | wxLEFT | wxGROW, 5 );
    convertsizer->Add(5, 0, 0);
    convertsizer->Add(progress, 1, wxGROW | wxTOP , 5 );
    previewsizer->Add(convertsizer, 0,  wxTOP |wxBOTTOM |wxGROW, 5 );

    panelsizer = new wxBoxSizer( wxHORIZONTAL );

    panelsizer->Add(leftsizer, 0, wxGROW|wxRIGHT|wxLEFT, 10);
    panelsizer->Add(middlesizer, 0,wxGROW|wxRIGHT|wxLEFT, 10);
    panelsizer->Add(previewsizer, 1,wxGROW|wxRIGHT|wxLEFT, 10);

   panelsizer->SetSizeHints( this );   // set size hints to honour minimum size
   panel->SetSizer( panelsizer );      // use the sizer for layout

   CreateStatusBar(2);
   if (!lastProject.IsEmpty() && lastProject != defaultProjectPath){
     wxString pName, pExt;
     wxFileName::SplitPath(lastProject.c_str(), NULL, &pName, &pExt);
     SetStatusText(wxString::Format("%s.%s", pName.c_str(), pExt.c_str()).Upper(),0);
   }else {
     SetStatusText(fcStrings->Read("l041", wxEmptyString).Upper(),0);
   }
   SetStatusText(fcStrings->Read("l024", wxEmptyString),1);

   fillChoiceCtrl(themeChoice, wxString(dataDir.getThemePath().c_str()), "*.style");
   fillChoiceCtrl(reformatChoice, wxString(dataDir.getIndentSchemesPath().c_str()),
                   "*.indent");
   middlesizer->Layout();Refresh(); Update();

   assignToolTip(butSource,"t001");
   assignToolTip(butOutDir,"t002");
   assignToolTip(butChooseStyleInfile,"t003");
   assignToolTip(butClearList,"t004");
   assignToolTip(styleOutFileName,"t005");
   assignToolTip(styleInFileName,"t006");
   assignToolTip(outDir,"t007");
   assignToolTip(includeStyle,"t008");
   assignToolTip(inlineCSS,"t033");
   assignToolTip(fragment,"t009");
   assignToolTip(enclosePreTag,"t035");
   assignToolTip(linenumbers,"t010");
   assignToolTip(attachAnchors,"t011");
   assignToolTip(useFileAsAnchorName,"t029");
   assignToolTip(reformatCode,"t012");
   assignToolTip(outputFormatChoice,"t013");
   assignToolTip(butStart,"t014");
   assignToolTip(generateHtmlIndex,"t015");
   assignToolTip(reformatChoice,"t016");
   assignToolTip(themeChoice,"t017");
   assignToolTip(wrapLines,"t018");
   assignToolTip(wrapLinesIntelligent,"t019");
   assignToolTip(replaceLatexQuotes,"t020");
   assignToolTip(enableLaTeXBabelCompat,"t027");
   assignToolTip(tabWidth,"t021");
   assignToolTip(lineLength,"t031");
   assignToolTip(lnFillZeroes,"t022");
   assignToolTip(writeToSourceDir,"t023");
   assignToolTip(butRemoveSelection,"t024");
   assignToolTip(useEncoding,"t025");
   assignToolTip(orderedList,"t026");
   assignToolTip(pageSizeChoice,"t028");
   assignToolTip(changeCase,"t032");
   assignToolTip(butClipboard,"t034");
   assignToolTip(preview,"t030");

   assignToolTip(cbCustomFont,"t036");
   assignToolTip(fontFace,"t037");
   assignToolTip(fontSize,"t038");
   assignToolTip(svgWidth,"t039");
   assignToolTip(svgHeight,"t040");
   assignToolTip(cbRTFAddCharStyles,"t041");
   assignToolTip(useTagsInfo, "t042");
   assignToolTip(btTagsInFile, "t043");

   wxFFile txtFile (string(dataDir.getExtDir()+"fileopenfilter.conf").c_str(), "r");
   txtFile.ReadAll(&fileFilter);
   fileFilter.Replace("\n",""); // wegen GTK

   if (fileFilter.IsEmpty()){
     fileFilter="All source code (*.*)|*.*|";
   }

   bool extensionsFound=loadFileTypeConfig(&extensions, &shebangs);
   if (!extensionsFound){
     wxMessageBox(fcStrings->Read(("e008"), wxEmptyString),
                           fcStrings->Read(("l025"), wxEmptyString),
                           wxICON_EXCLAMATION);
   }

   loadProject(currentProjectPath);

   if (x>0 && y > 0) {
          //this->Move(x,y);
          this-> SetSize( x, y, width, height, 0);
   } else {
          this->Centre();
   }

#ifndef __WXMAC__
   // initialize drag and drop
   listBox->SetDropTarget (new DropFiles (this));
#endif

}

bool HighlightFrame::loadLanguage(const wxString &newLanguage){
    wxString i18nPath=wxString::Format("%s%s.txt", dataDir.getI18nDir().c_str(),
                                                   newLanguage.c_str() );

   fcStrings= new wxFileConfig ("highlight-gui", wxEmptyString, i18nPath,
				wxEmptyString, wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_NO_ESCAPE_CHARACTERS
				#ifdef WIN32
				| wxCONFIG_USE_RELATIVE_PATH
				#endif
);
   if (!fcStrings || !fcStrings->GetNumberOfEntries()){
      wxString errMsg=wxString::Format("Could not load GUI language file (%s). Check installation.",
                    i18nPath.c_str());
      wxMessageBox(errMsg, "Highlight Fatal Error", wxICON_EXCLAMATION);
      return false;
    }
    language=newLanguage;
    return true;
}

bool HighlightFrame::loadFileTypeConfig(StringMap* extMap, StringMap* shebangMap) {
  if (!extMap || !shebangMap) return false;

  ConfigurationReader config(dataDir.getConfDir() + "filetypes.conf");
  if (config.found())
  {
        stringstream values;
        string paramName, paramVal;
        for (unsigned int i=0;i<config.getParameterNames().size();i++){
            paramName = config.getParameterNames()[i];
            if (paramName.find("ext") != string::npos){
                values.str(StringTools::change_case(config.getParameter(paramName)));
                paramName = StringTools::getParantheseVal(paramName);
            	while (values >> paramVal) {
	   		        extMap->insert(make_pair( paramVal,  paramName));
            	}
            	values.clear();
            } else if (paramName.find("shebang") != string::npos){
                values.str(config.getParameter(paramName)) ;
		        paramName = StringTools::getParantheseVal(paramName);
            	while (values >> paramVal) {
                    shebangMap->insert(make_pair( paramVal,  paramName));
            	}
            	values.clear();
            }
        }
        return true;
  }
  return false;
}

void HighlightFrame::OnClickButtonSource(wxCommandEvent & WXUNUSED(event))
{
  wxArrayString chosenFiles;
  wxFileDialog openFiles(this,fcStrings->Read("l001", wxEmptyString),
                         openFileDir, "", fileFilter,
                         wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST);
  openFiles.ShowModal();
  openFiles.GetFilenames(chosenFiles);
  openFileDir=openFiles.GetDirectory();
  if (openFileDir[openFileDir.length()-1] != Platform::pathSeparator ) {
    openFileDir += Platform::pathSeparator;
  }
  if (outDir->GetValue().IsEmpty()){
      outDir->SetValue(openFileDir);
  }
  addInputFiles(chosenFiles, openFileDir, false);
}

void HighlightFrame::OnTips(wxCommandEvent & WXUNUSED(event)){
  showStartupTips(true);
}

void HighlightFrame::addInputFiles(const wxArrayString& inputFiles,
                               const wxString &prefix, bool clear){
  wxString absInFilePath;
  if (clear) listBox->Clear();
  for (unsigned int i=0; i< inputFiles.GetCount(); i++){
     absInFilePath.Printf(("%s%s"), prefix.c_str(), inputFiles[i].GetData());
     if (listBox->FindString(absInFilePath) == -1) {
       listBox->Append(absInFilePath);
     }
  }
}

void HighlightFrame::OnClickButtonTargetDir(wxCommandEvent & WXUNUSED(event))
{
  wxDirDialog targetDir(this,fcStrings->Read("l002", wxEmptyString), (""));
  targetDir.ShowModal();
  outDir->SetValue(targetDir.GetPath());
}

void HighlightFrame::OnClickButtonClear(wxCommandEvent & WXUNUSED(event)){
  listBox->Clear();
}

void HighlightFrame::OnClickButtonFontDlg(wxCommandEvent & WXUNUSED(event)){
  wxFont fontInit;
  fontInit.SetFaceName("Courier New");
  fontInit.SetPointSize(10);
  wxFont font = wxGetFontFromUser(this,  fontInit, wxEmptyString);
  if (font.IsOk()){
     wxString fontFaceVal=font.GetFaceName();
     wxString fontSizeVal;
     fontSizeVal.Printf("%d", font.GetPointSize());
     fontFace->SetValue(fontFaceVal);
     fontSize->SetValue(fontSizeVal);
  }
}

void HighlightFrame::OnClickButtonRemSelection(wxCommandEvent &event){
  wxArrayInt selectedItems;
  listBox->GetSelections (selectedItems);
  size_t cnt = selectedItems.GetCount();
  if (cnt){
    for (size_t i=0;i<cnt;i++){
      listBox->Delete(selectedItems[i]-i);
    }
  }
}

void HighlightFrame::OnHelp(wxCommandEvent & WXUNUSED(event)){
   showTextFile("README");
}
void HighlightFrame::OnLicense(wxCommandEvent & WXUNUSED(event)){
   showTextFile("COPYING");
}
void HighlightFrame::OnChangelog(wxCommandEvent & WXUNUSED(event)){
   showTextFile("ChangeLog");
}

void HighlightFrame::OnCheckLanguage(wxCommandEvent & event){
  bool langFound=loadLanguage(menuLang->GetLabel( event.GetId()).c_str());
  if (langFound){
    wxMessageBox(fcStrings->Read("l026", wxEmptyString),
                 fcStrings->Read("l019", wxEmptyString),
                 wxICON_INFORMATION);
  }
}

void HighlightFrame::OnStyleOutfileChanged(wxCommandEvent & WXUNUSED(event)){
    setStyleInLabel();
}

void HighlightFrame::OnClickButtonOpenStyleFile(wxCommandEvent & WXUNUSED(event))
{
  wxFileDialog openFiles(this,fcStrings->Read("l001", wxEmptyString),"", "",
                         (outputFormatChoice->GetSelection()<2 || outputFormatChoice->GetSelection()==5) ?
                            "CSS input file (*.css)|*.css|":"LaTeX style (*.sty)|*.sty|",
                         wxFD_FILE_MUST_EXIST );
  openFiles.ShowModal();
  if (!openFiles.GetFilename().IsEmpty()){
    wxString chosenFile=openFiles.GetDirectory();
    chosenFile.Append(Platform::pathSeparator);
    chosenFile.Append(openFiles.GetFilename());
    styleInFileName->SetValue(chosenFile);
  }
}

void HighlightFrame::OnClickButtonOpenTagsFile(wxCommandEvent & WXUNUSED(event))
{
  wxFileDialog openFiles(this,fcStrings->Read("l001", wxEmptyString),"", "",
                         "Ctags input file (*)|*|",
                         wxFD_FILE_MUST_EXIST );
  openFiles.ShowModal();
  if (!openFiles.GetFilename().IsEmpty()){
    wxString chosenFile=openFiles.GetDirectory();
    chosenFile.Append(Platform::pathSeparator);
    chosenFile.Append(openFiles.GetFilename());
    tagsPath->SetValue(chosenFile);
  }
}

void HighlightFrame::OnClickSaveProject(wxCommandEvent & WXUNUSED(event))
{
  wxFileDialog openFiles(this,fcStrings->Read("l040", wxEmptyString),"", "",
                         "Highlight Project (*.hpr)|*.hpr|" ,
                         wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
  openFiles.ShowModal();
  if (!openFiles.GetFilename().IsEmpty()){
    wxString chosenFile=openFiles.GetDirectory();
    chosenFile.Append(Platform::pathSeparator);
    chosenFile.Append(openFiles.GetFilename());
    if (writeProject(chosenFile.c_str())){
        SetStatusText(openFiles.GetFilename().Upper(),0);
        currentProjectPath=chosenFile;
    }
  }
}

void HighlightFrame::OnClickOpenProject(wxCommandEvent & WXUNUSED(event))
{
  wxFileDialog openFiles(this,fcStrings->Read("l001", wxEmptyString), "", "",
                        "Highlight Project (*.hpr)|*.hpr|",
                         wxFD_FILE_MUST_EXIST );
  openFiles.ShowModal();
  if (!openFiles.GetFilename().IsEmpty()){
    wxString chosenFile=openFiles.GetDirectory();
    chosenFile.Append(Platform::pathSeparator);
    chosenFile.Append(openFiles.GetFilename());
    if (loadProject(chosenFile)){
        SetStatusText(openFiles.GetFilename().Upper(),0);
        currentProjectPath=chosenFile;
    }
  }
}

void HighlightFrame::OnClickDefaultProject(wxCommandEvent & WXUNUSED(event))
{
    if (loadProject(defaultProjectPath)){
        SetStatusText(fcStrings->Read("l041", wxEmptyString).Upper(),0);
        currentProjectPath=defaultProjectPath;
    }
}

void HighlightFrame::OnQuit2(wxCommandEvent & WXUNUSED(event)){
     Close(true); // ruft OnQuit auf
}

void HighlightFrame::OnClickElement(wxCommandEvent & event){
     plausiChecks();
     event.Skip();
}

void HighlightFrame::OnUpdatePreview(wxCommandEvent & event){
     updatePreview();
     event.Skip();
}

void HighlightFrame::OnQuit(wxCloseEvent & WXUNUSED(event))
{
  wxString userDataDir =  wxString(userPrefBaseDir.c_str());
  if (!wxDirExists(userDataDir)) wxMkdir(userDataDir);
  if (!writePreferences()) {
    wxMessageBox (fcStrings->Read("e006", wxEmptyString),
                  fcStrings->Read("l025", wxEmptyString), wxICON_EXCLAMATION);
  }
  writeProject(currentProjectPath);
  if (fcStrings) delete fcStrings;
  this->Destroy();
}

void HighlightFrame::OnAbout(wxCommandEvent & WXUNUSED(event)){
   wxString translatorsList;
   wxFFile txtFile (string(dataDir.getI18nDir()+"Translators.list").c_str(), ("r"));
   txtFile.ReadAll(&translatorsList);

   if (translatorsList.IsEmpty()){
     translatorsList="Error: File Translators.list not found.\n";
   }
   wxString formatMsg;
   formatMsg.Printf(MSG_INFO_TXT, HIGHLIGHT_VERSION, wxMAJOR_VERSION,
                    wxMINOR_VERSION, wxRELEASE_NUMBER,
                    translatorsList.c_str(),HIGHLIGHT_URL);
   wxMessageBox(formatMsg,fcStrings->Read("l019", wxEmptyString),
                wxICON_INFORMATION);
}

void HighlightFrame::showTextFile(const wxString &file){
   wxString cmd;
   cmd.Printf("%s%s",dataDir.getDocDir().c_str(),file.c_str());
   ShowFileDlg dlg(this, -1,file, cmd );
   if (dlg.fileFound()){
      dlg.ShowModal();
   }
}

void HighlightFrame::assignToolTip(wxWindow* widget, const char* tipName){
   wxString tip = fcStrings->Read(tipName, wxEmptyString);
   tip.Replace(("\\n"), ("\n"));
   widget ->SetToolTip(tip);
}

void HighlightFrame::fillChoiceCtrl(wxChoice* choice, const wxString &dir,
                                    const wxString &ext){
   if (!choice) return;

   wxFileName fName;
   wxArrayString files;
   wxDir::GetAllFiles(dir, &files, ext);
   for (unsigned int i=0;i<files.GetCount(); i++){
     fName.Assign(files[i]);
     choice->Append(fName.GetName());
   }
   choice->SetSelection(0);
}

void HighlightFrame::showStartupTips(bool forceTips){
  if (showTips || forceTips ){
     wxString tipsFile;
     tipsFile.Printf("%s%s.tips",dataDir.getI18nDir().c_str(), language.c_str());
     if (!::wxFileExists(tipsFile)){
       tipsFile.Printf("%s%s.tips", dataDir.getI18nDir().c_str(), "English");
     }
     wxTipProvider *tipProvider = wxCreateFileTipProvider(tipsFile, lastTip);
     showTips=wxShowTip(this, tipProvider,showTips);
     lastTip=tipProvider->GetCurrentTip();
     delete tipProvider;
  }
}

void HighlightFrame::plausiChecks(){

  highlight::OutputType outType = getOutputType();
  bool webOutput=outType==highlight::HTML || outType==highlight::XHTML;
  bool texOutput =   outType==highlight::TEX || outType==highlight::LATEX;
  bool svgOutput =  outType==highlight::SVG;
  bool rtfOutput =  outType==highlight::RTF;

  bool extStyleEnabled=(webOutput || texOutput || svgOutput);
  bool write2outdir = !writeToSourceDir ->GetValue();
  includeStyle->Enable(extStyleEnabled || !write2outdir );
  fragment->Enable (!svgOutput && outputFormatChoice->GetSelection()!=4);
  inlineCSS->Enable(includeStyle->GetValue() && webOutput);
  if (!includeStyle->GetValue()) inlineCSS->SetValue(0);
  inlineCSS->Show(webOutput);
  enclosePreTag->Enable(fragment->GetValue() && webOutput); //
  enclosePreTag->Show( webOutput);

  attachAnchors->Enable(linenumbers->GetValue() && webOutput); //
  attachAnchors->Show(webOutput);
  useFileAsAnchorName->Enable(attachAnchors->IsEnabled() && attachAnchors->GetValue()); //
  useFileAsAnchorName->Show(webOutput);
  orderedList->Enable(linenumbers->GetValue() && webOutput); //
  orderedList->Show(webOutput);
  lnFillZeroes->Enable(linenumbers->GetValue()&&(!(orderedList->GetValue())||!webOutput));
  reformatChoice->Enable(reformatCode->GetValue());
  caseChoice->Enable(changeCase->GetValue());
  wrapLinesIntelligent->Enable(wrapLines->GetValue());
  replaceLatexQuotes->Enable(outputFormatChoice->GetSelection()==2        // L
                             && fragment->GetValue());
  enableLaTeXBabelCompat->Show(outputFormatChoice->GetSelection()==2 ); // L
  replaceLatexQuotes->Show(outputFormatChoice->GetSelection()==2);

  cbRTFAddCharStyles->Show(rtfOutput);

  lblTabWidth->Enable(!reformatCode->GetValue());
  tabWidth->Enable(!reformatCode->GetValue());
  lineLength->Enable(wrapLines->GetValue());
  generateHtmlIndex->Enable(webOutput && write2outdir); //
  generateHtmlIndex->Show(webOutput);

  tagsPath->Enable(useTagsInfo->GetValue());
  btTagsInFile->Enable(useTagsInfo->GetValue());
  useTagsInfo->Show(webOutput);
  tagsPath->Show(webOutput);
  btTagsInFile->Show(webOutput);

  lblOutDir ->Enable(write2outdir);
  butOutDir->Enable(write2outdir);
  outDir->Enable(write2outdir);
  if (!write2outdir)  includeStyle->SetValue(extStyleEnabled);

  if (extStyleEnabled){
    checkStyleReferences(styleOutFileName, webOutput||svgOutput);
    checkStyleReferences(styleInFileName, webOutput||svgOutput);
  }
  bool enableEncoding =    outputFormatChoice->GetSelection()<3
                        || outputFormatChoice->GetSelection()>4;
  useEncoding->Enable(enableEncoding);
  encodingChoice->Enable(enableEncoding && useEncoding->GetValue());

  pageSizeChoice->Show(rtfOutput);
  lblPageSize->Show(rtfOutput);

  styleOutFileName->Enable(extStyleEnabled && !includeStyle->GetValue()&&write2outdir);
  lblStyleOut->Enable(extStyleEnabled&&!includeStyle->GetValue()&&write2outdir);
  styleInFileName->Enable(extStyleEnabled);
  lblStyleIn->Enable(extStyleEnabled);
  butChooseStyleInfile->Enable(extStyleEnabled);
  if (webOutput && inlineCSS->GetValue()){
    lblStyleIn->Enable(inlineCSS->IsEnabled() && !inlineCSS->GetValue());
    styleInFileName->Enable(inlineCSS->IsEnabled() && !inlineCSS->GetValue());
    butChooseStyleInfile->Enable(inlineCSS->IsEnabled() && !inlineCSS->GetValue());
  }

  lblSVGSize->Show(svgOutput);
  svgWidth->Show(svgOutput);
  lblSVGx->Show(svgOutput);
  svgHeight->Show(svgOutput);

  fontFace->Enable(cbCustomFont->GetValue());
  fontSize->Enable(cbCustomFont->GetValue());
  btFontDlg->Enable(cbCustomFont->GetValue() && !texOutput);
  lblFontSize->Enable(cbCustomFont->GetValue());
  lblFontFace->Enable(cbCustomFont->GetValue());

  setStyleInLabel();

  if (lastOutType!=outType){
    wxSize oldSize=this->GetSize();
    panelsizer->SetSizeHints( this );
    this->Layout();
    this->Refresh();
    this-> SetSize(oldSize);
    lastOutType = outType;
  }
}

void HighlightFrame::checkStyleReferences(wxTextCtrl *styleCtrl, bool webOutput){
    wxString stylePath = styleCtrl->GetValue();
    if (stylePath.Matches( (webOutput)? "*.sty" : "*.css")) {
      stylePath.Printf((webOutput)? "%s.css":"%s.sty",
                       stylePath.Mid(0, stylePath.Length()-4).c_str());
      styleCtrl->SetValue (stylePath);
    }
}

void HighlightFrame::setStyleInLabel(){
    wxString str=wxString::Format("%s %s",fcStrings->Read("l011", wxEmptyString).c_str(),
              ( (includeStyle->GetValue()) ? fcStrings->Read("l035", wxEmptyString).c_str():
                  ((styleOutFileName!=NULL)?(styleOutFileName->GetValue()).c_str():
                                           CSS_DEFAULT_NAME )));
    lblStyleIn->SetLabel(str);
}

bool HighlightFrame::writePreferences(){
    wxFileConfig test ("highlight-gui", wxEmptyString, preferencesPath,
			wxEmptyString, wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_NO_ESCAPE_CHARACTERS);
    test.DeleteAll();
    test.Write("language",language);
    test.Write("showTips",showTips);
    test.Write("lastTip",lastTip);
    test.Write("lastProject",currentProjectPath);
    int x=0, y=0, width=0, height=0;
    this->GetPosition(&x,&y);
    this->GetSize(&width,&height);
    test.Write("winXPos",x);
    test.Write("winYPos",y);
    test.Write("winWidth",width);
    test.Write("winHeight",height);
    test.Write("version",HIGHLIGHT_VERSION);
    return test.Flush();
}

bool HighlightFrame::writeProject(const wxString& projectFile){
    wxFileConfig prjFile ("highlight-gui", wxEmptyString, projectFile,
                          wxEmptyString, wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_NO_ESCAPE_CHARACTERS);
    prjFile.DeleteAll();
    prjFile.Write(("outDir"),outDir->GetValue());
    prjFile.Write(("outputFormatChoice"),outputFormatChoice->GetSelection());
    prjFile.Write(("styleOutFileName"),styleOutFileName->GetValue());
    prjFile.Write(("styleInFileName"),styleInFileName->GetValue());
    prjFile.Write(("themeChoice"), themeChoice->GetSelection());
    prjFile.Write(("openFileDir"), openFileDir);
    prjFile.Write(("includeStyle"), includeStyle->GetValue());
    prjFile.Write(("inlineCSS"), inlineCSS->GetValue());
    prjFile.Write(("fragment"), fragment->GetValue());
    prjFile.Write(("enclosepretag"), enclosePreTag->GetValue());
    prjFile.Write(("linenumbers"), linenumbers->GetValue());
    prjFile.Write(("attachAnchors"), attachAnchors->GetValue());
    prjFile.Write(("useFileAsAnchorName"), useFileAsAnchorName->GetValue());
    prjFile.Write(("reformatCode"), reformatCode->GetValue());
    prjFile.Write(("reformatChoice"), reformatChoice->GetSelection());
    prjFile.Write(("changeCase"), changeCase->GetValue());
    prjFile.Write(("caseChoice"), caseChoice->GetSelection());
    prjFile.Write(("encodingChoice"), encodingChoice->GetValue());
    prjFile.Write(("useEncoding"), useEncoding->GetValue());
    prjFile.Write(("generateHtmlIndex"), generateHtmlIndex->GetValue());
    prjFile.Write(("wrapLines"), wrapLines->GetValue());
    prjFile.Write(("wrapLinesIntelligent"), wrapLinesIntelligent->GetValue());
    prjFile.Write(("replaceLatexQuotes"), replaceLatexQuotes->GetValue());
    prjFile.Write(("enableLaTeXBabelCompat"), enableLaTeXBabelCompat->GetValue());
    prjFile.Write(("tabWidth"), tabWidth->GetValue());
    prjFile.Write(("lineLength"), lineLength->GetValue());
    prjFile.Write(("lnFillZeroes"), lnFillZeroes->GetValue());
    prjFile.Write(("writeToSourceDir"), writeToSourceDir->GetValue());
    prjFile.Write(("orderedList"), orderedList->GetValue());
    prjFile.Write(("pageSizeChoice"), pageSizeChoice->GetSelection());

    prjFile.Write(("customFont"), cbCustomFont->GetValue());
    prjFile.Write(("fontFace"), fontFace->GetValue());
    prjFile.Write(("fontSize"), fontSize->GetValue());
    prjFile.Write(("svgWidth"), svgWidth->GetValue());
    prjFile.Write(("svgHeight"), svgHeight->GetValue());
    prjFile.Write(("charStyles"), cbRTFAddCharStyles->GetValue());
    prjFile.Write(("useTagsInfo"), useTagsInfo->GetValue());
    prjFile.Write(("tagsPath"), tagsPath->GetValue());

    for (int fileCount=0; fileCount < listBox->GetCount(); fileCount++)
      {
         prjFile.Write(wxString::Format(("inputfile_%d"), fileCount), listBox->GetString(fileCount));
      }

    return prjFile.Flush();
}


bool HighlightFrame::loadProject(const wxString& projectFile){
    wxFileConfig prjFile ("highlight-gui", wxEmptyString, projectFile, wxEmptyString,
                          wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_NO_ESCAPE_CHARACTERS);
    long lVal=0L;
    bool bVal=false;

    outDir->SetValue(prjFile.Read("outDir", ""));
    openFileDir=prjFile.Read("openFileDir", "").c_str();
    tabWidth->SetValue(prjFile.Read("tabWidth", "4"));
    lineLength->SetValue(prjFile.Read("lineLength", "80"));
    styleOutFileName->SetValue(prjFile.Read("styleOutFileName", "highlight.css" ));
    styleInFileName->SetValue(prjFile.Read("styleInFileName", ""));
    encodingChoice->SetValue(prjFile.Read("encodingChoice", "ISO-8859-1") );
    fontFace->SetValue(prjFile.Read("fontFace", ""));
    fontSize->SetValue(prjFile.Read("fontSize", ""));
    svgWidth->SetValue(prjFile.Read("svgWidth", ""));
    svgHeight->SetValue(prjFile.Read("svgHeight", ""));
    tagsPath->SetValue(prjFile.Read("tagsPath", ""));

    prjFile.Read(("outputFormatChoice"), &lVal, 0L); outputFormatChoice->SetSelection(lVal);
    prjFile.Read(("themeChoice"), &lVal, 0L); themeChoice->SetSelection(lVal);
    prjFile.Read(("reformatChoice"), &lVal, 0L); reformatChoice->SetSelection(lVal);
    prjFile.Read(("caseChoice"), &lVal, 0L); caseChoice->SetSelection(lVal);
    prjFile.Read(("pageSizeChoice"), &lVal, 1L); pageSizeChoice->SetSelection(lVal);
    prjFile.Read(("includeStyle"), &bVal, false); includeStyle->SetValue(bVal);
    prjFile.Read(("inlineCSS"), &bVal, false); inlineCSS->SetValue(bVal);
    prjFile.Read(("fragment"), &bVal, false); fragment->SetValue(bVal);
    prjFile.Read(("enclosepretag"), &bVal, false); enclosePreTag->SetValue(bVal);
    prjFile.Read(("linenumbers"), &bVal, false); linenumbers->SetValue(bVal);
    prjFile.Read(("attachAnchors"), &bVal, false); attachAnchors->SetValue(bVal);
    prjFile.Read(("useFileAsAnchorName"), &bVal, false); useFileAsAnchorName->SetValue(bVal);
    prjFile.Read(("reformatCode"), &bVal, false); reformatCode->SetValue(bVal);
    prjFile.Read(("changeCase"), &bVal, false); changeCase->SetValue(bVal);
    prjFile.Read(("generateHtmlIndex"), &bVal, false); generateHtmlIndex->SetValue(bVal);
    prjFile.Read(("wrapLines"), &bVal, false); wrapLines->SetValue(bVal);
    prjFile.Read(("wrapLinesIntelligent"), &bVal, false); wrapLinesIntelligent->SetValue(bVal);
    prjFile.Read(("replaceLatexQuotes"), &bVal, false); replaceLatexQuotes->SetValue(bVal);
    prjFile.Read(("enableLaTeXBabelCompat"), &bVal, false); enableLaTeXBabelCompat->SetValue(bVal);
    prjFile.Read(("lnFillZeroes"), &bVal, false); lnFillZeroes->SetValue(bVal);
    prjFile.Read(("useEncoding"), &bVal, false); useEncoding->SetValue(bVal);
    prjFile.Read(("orderedList"), &bVal, false); orderedList->SetValue(bVal);
    prjFile.Read(("customFont"), &bVal, false); cbCustomFont->SetValue(bVal);
    prjFile.Read(("charStyles"), &bVal, false); cbRTFAddCharStyles->SetValue(bVal);
    prjFile.Read(("useTagsInfo"), &bVal, false); useTagsInfo->SetValue(bVal);

    int fileCount=0;
    wxString infile;
    bool done=false;
    listBox->Clear();
    while (!done){
        infile = prjFile.Read(wxString::Format(("inputfile_%d"), fileCount),"");
        fileCount++;
        if (!infile.empty()){
             if (listBox->FindString(infile) == -1) {
                listBox->Append(infile);
             }
        } else {
             done = true;
        }
    }
    setStyleInLabel();
    plausiChecks();
    return true;
}

void HighlightFrame::applyCtrlValues(highlight::CodeGenerator* generator, bool previewMode){
    if (!generator) return;

    if (!previewMode) {
	generator->setStyleInputPath(styleInFileName->GetValue());
	generator->setStyleOutputPath(styleOutFileName->GetValue());
	generator->setIncludeStyle(includeStyle->GetValue());
	generator->setFragmentCode(fragment->GetValue());

	generator->setHTMLAttachAnchors(attachAnchors->GetValue());
	generator->setHTMLOrderedList(orderedList->GetValue());
	generator->setHTMLInlineCSS(inlineCSS->GetValue());
	generator->setHTMLEnclosePreTag(enclosePreTag->GetValue());

	generator->setLATEXReplaceQuotes(replaceLatexQuotes->GetValue());
	generator->setLATEXNoShorthands(enableLaTeXBabelCompat->GetValue());

	generator->setRTFPageSize(pageSizeChoice->GetStringSelection().Lower());
	generator->setRTFCharStyles(cbRTFAddCharStyles->GetValue());

	generator->setSVGSize(svgWidth->GetValue(),svgHeight->GetValue());
    }

    generator->setPrintLineNumbers(linenumbers->GetValue());
    generator->setPrintZeroes(lnFillZeroes->IsEnabled() && lnFillZeroes->GetValue());

    wxString stylePath=wxString::Format(("%s%s.style"), dataDir.getThemePath().c_str(),
                                   themeChoice->GetStringSelection().c_str());
    generator->initTheme(stylePath);

    generator->setPreformatting(getWrappingStyle(),
                               (generator->getPrintLineNumbers()) ?
                                lineLength->GetValue() - 5 : lineLength->GetValue(),
                                tabWidth->GetValue());

    if (useEncoding->GetValue()) {
        generator->setEncoding((encodingChoice->GetValue()));
    } else {
        generator->setEncoding("none");
    }
    if (changeCase->GetValue()) {
	StringTools::KeywordCase kwCase=StringTools::CASE_UNCHANGED;
	switch (caseChoice->GetSelection()){
		case 0: kwCase=StringTools::CASE_UPPER; break;
		case 1: kwCase=StringTools::CASE_LOWER; break;
		case 2: kwCase=StringTools::CASE_CAPITALIZE; break;
	}
        generator->setKeyWordCase(kwCase);
    }

    if (cbCustomFont->GetValue()){
      generator->setBaseFont(fontFace->GetValue()) ;
      generator->setBaseFontSize(fontSize->GetValue()) ;
    }
    generator->setLineNumberWidth(5);

    if (reformatCode->GetValue()){
       wxString indentSchemePath=wxString::Format(("%s%s.indent"),
                                  dataDir.getIndentSchemesPath().c_str(),
                                  reformatChoice->GetStringSelection().c_str());
      generator->initIndentationScheme(indentSchemePath);
    }
}


void HighlightFrame::OnClickButtonClipboard(wxCommandEvent & WXUNUSED(event)){

    wxArrayInt selections;
    listBox->GetSelections(selections);
    if (!selections.GetCount()) return;

    wxBeginBusyCursor();
    butStart->Disable();
    butClipboard->Disable();
    SetStatusText(fcStrings->Read(("l044"), wxEmptyString),1);
    auto_ptr<highlight::CodeGenerator> generator(highlight::CodeGenerator::getInstance(getOutputType()));

    applyCtrlValues(generator.get());

    if (useTagsInfo->GetValue() && outputFormatChoice->GetSelection()<2 && !tagsPath->GetValue().IsEmpty()) {
      if (!generator->initTagInformation(tagsPath->GetValue())){
         wxMessageBox(fcStrings->Read(("l058"), "Could not load Tags file"),
                     fcStrings->Read(("l025"), wxEmptyString), wxICON_EXCLAMATION);
         return;
      }
    }

    wxString currentInputFile= listBox->GetString(selections.Item(0));
    string suffix = getFileType(getFileSuffix(currentInputFile), currentInputFile);
    string langDefPath = dataDir.getLangPath() + suffix + ".lang";
    string::size_type pos=currentInputFile.Find(Platform::pathSeparator, true);
    wxString inFileName = currentInputFile.Mid(pos+1);

    if (useFileAsAnchorName->GetValue()){
       generator->setHTMLAnchorPrefix(inFileName);
    }
    generator->setTitle(inFileName);

    wxString *clipboardData=NULL;
    if (generator->initLanguage(langDefPath)!=highlight::LOAD_FAILED) {
          clipboardData =new wxString(generator->generateStringFromFile(currentInputFile));
    }
    if (clipboardData && wxTheClipboard->Open()) {
      // This data objects are held by the clipboard,
      // so do not delete them in the app.
      // extDataObject* pDataObject = new extDataObject(clipboardData);
      wxCustomDataObject* pDataObject = new wxCustomDataObject(wxDF_TEXT);

      wxDataFormat f (wxDF_TEXT);
      switch (outputFormatChoice->GetSelection()){
       // case 0: //HTML
       // case 1: //XHTML
                //f.SetId(("text/html")); //w32 nok
       //         break;
       // case 2: //LATEX;
       // case 3: //TEX;
                //f.SetId(("text/plain"));
           //     break;
        case 4: //RTF;
#ifdef WIN32
                f.SetId(("Rich Text Format")); // w32 OK
#else
                f.SetId(("text/rtf")); // gtk OK
#endif
                break;
       // case 5:  //XML
                //f.SetId(("text/xml")); // w32 nok
         //       break;
      }
      pDataObject->SetFormat(f);
      pDataObject->SetData(clipboardData->Length(), clipboardData->c_str());

      wxTheClipboard->SetData(pDataObject); // do not delete pDataObject
      wxTheClipboard->Close();
    }

    wxEndBusyCursor();
    butStart->Enable();
    butClipboard->Enable();
    SetStatusText(fcStrings->Read(("l024"), wxEmptyString),1);
}

void HighlightFrame::OnClickButtonStart(wxCommandEvent & WXUNUSED(event)){

    if (!listBox->GetCount() )
        return;

    if (!writeToSourceDir->GetValue() && !wxDir::Exists(outDir->GetValue()))
    {
      wxMessageBox(fcStrings->Read("l020", wxEmptyString),
                   fcStrings->Read("l025", wxEmptyString), wxICON_EXCLAMATION);
      outDir->SetFocus();
      return;
    }
    if ((outputFormatChoice->GetSelection()<2 || outputFormatChoice->GetSelection()==5)
        && includeStyle->GetValue()==false
        && styleOutFileName->GetValue().IsEmpty())
    {
      wxMessageBox(fcStrings->Read("l021", wxEmptyString),
                   fcStrings->Read("l025", wxEmptyString), wxICON_EXCLAMATION);
      styleOutFileName->SetFocus();
      return;
    }

    wxStopWatch stopWatch;

    auto_ptr<highlight::CodeGenerator> generator(highlight::CodeGenerator::getInstance(getOutputType()));

    applyCtrlValues(generator.get());


    if (useTagsInfo->GetValue() && outputFormatChoice->GetSelection()<2 && !tagsPath->GetValue().IsEmpty()) {
      if (!generator->initTagInformation(tagsPath->GetValue())){
         wxMessageBox(fcStrings->Read(("l058"), "Could not load Tags file"),
                     fcStrings->Read(("l025"), wxEmptyString), wxICON_EXCLAMATION);
         return;
      }
    }

    string outfileName;
    string langDefPath;
    string suffix;
    string outfileSuffix = getOutFileSuffix();
    int fileCount=0;
    highlight::ParseError error;
    highlight::LoadResult loadRes;
    wxArrayString reformatFailures, outputFailures, inputFailures;
    wxString currentInputFile;

    SetStatusText(fcStrings->Read(("l017"), wxEmptyString),1);

    wxBeginBusyCursor();
    butStart->Disable();
    butClipboard->Disable();

    string outPath((outDir->GetValue()).c_str());
    if (outPath[outPath.length()-1] != Platform::pathSeparator ) {
      outPath +=Platform::pathSeparator;
    }

    for (fileCount=0; fileCount < listBox->GetCount(); fileCount++){

       currentInputFile= listBox->GetString(fileCount);
       suffix = getFileType(getFileSuffix(currentInputFile), currentInputFile);
       langDefPath = dataDir.getLangPath() + suffix + ".lang";
       loadRes=generator->initLanguage(langDefPath);
        if (loadRes==highlight::LOAD_FAILED_REGEX){
             wxString formatMsg;
             formatMsg.Printf("Invalid regular expression in %s:\n%s",
                               langDefPath.c_str(), generator->getLanguage().getFailedRegex().c_str());
             wxMessageBox(formatMsg, "Regex Error");
             break;
        } else  if (loadRes==highlight::LOAD_FAILED) {
          wxString formatMsg;
          formatMsg.Printf(fcStrings->Read(("e002"), wxEmptyString), suffix.c_str());
          wxMessageBox(formatMsg, fcStrings->Read(("l025"), wxEmptyString),
                       wxICON_EXCLAMATION);
       } else {
          if (reformatCode->GetValue()&& !generator->formattingIsPossible()){
             reformatFailures.Add(currentInputFile);
          }
          if (writeToSourceDir->GetValue()) { //write output to source directories?
            outfileName = string(currentInputFile.c_str());
          } else {
            outfileName = outPath;
            outfileName += wxFileName(currentInputFile).GetFullName().c_str();
          }
          outfileName += outfileSuffix;

          string::size_type pos=currentInputFile.Find(Platform::pathSeparator, true);
          wxString inFileName = currentInputFile.Mid(pos+1);

          if (useFileAsAnchorName->GetValue()){
            generator->setHTMLAnchorPrefix(inFileName);
          }
          generator->setTitle(inFileName);

          error = generator->generateFile(currentInputFile,
                                         outfileName );
          if (error != highlight::PARSE_OK){
            stopWatch.Pause();
            if (error == highlight::BAD_INPUT) {
              inputFailures.Add(currentInputFile);
            }
            else {
              outputFailures.Add(wxString(outfileName));
            }
            stopWatch.Resume();
          }
          progress->SetValue(100 * fileCount / listBox->GetCount());
	  wxYield();
       }
   }
   // print external style definition file
   if (includeStyle->IsEnabled() && !includeStyle->GetValue() &&
       (!inlineCSS->GetValue() || getOutputType()!= highlight::HTML  || getOutputType()!= highlight::XHTML)){
      string css_name = styleOutFileName->GetValue();
      string csspath = outPath;
      unsigned int pos = css_name.find_last_of(Platform::pathSeparator);
      if (pos == string::npos) {
         pos = css_name.find_last_of('/');
      }
      if ((pos != string::npos) && (pos < css_name.length())) {
         csspath += css_name.substr(pos+1, css_name.length());
      } else {
         csspath += css_name;
      }
      bool styleFileOK=generator -> printExternalStyle(csspath);

      if (!styleFileOK) {
         outputFailures.Add(wxString(csspath.c_str()));
      }
    }

    // print index file
    if (generateHtmlIndex->GetValue() && !writeToSourceDir->GetValue()) {
      vector <string>  fileList;
      for (int i=0; i < listBox->GetCount(); i++){
          fileList.push_back(string(listBox->GetString(i)));
       }
       bool indexFileOK=generator->printIndexFile(fileList,  outPath);
       if (!indexFileOK) {
          wxMessageBox(fcStrings->Read(("e007"), wxEmptyString),
                       fcStrings->Read(("l025"), wxEmptyString),
                       wxICON_EXCLAMATION);
       }
    }

   progress->SetValue(0);
   wxEndBusyCursor();
   butStart->Enable();
   butClipboard->Enable();

   wxString formatMsg;
   formatMsg.Printf(fcStrings->Read(("l023"), wxEmptyString), fileCount, stopWatch.Time());
   SetStatusText(formatMsg, 1);

   if (!reformatFailures.IsEmpty()||
       !inputFailures.IsEmpty() ||
       !outputFailures.IsEmpty()) {
       FailureDlg dlg(this, -1,fcStrings->Read(("l034"), wxEmptyString),
                      fcStrings->Read(("e010"), wxEmptyString), reformatFailures,
                      fcStrings->Read(("e003"), wxEmptyString), inputFailures,
                      fcStrings->Read(("e004"), wxEmptyString), outputFailures );
       dlg.ShowModal() ;
   }
}

highlight::WrapMode HighlightFrame::getWrappingStyle(){
  if (!wrapLinesIntelligent->GetValue() && wrapLinesIntelligent->IsEnabled())
     return highlight::WRAP_SIMPLE;
  return (wrapLines->GetValue())?highlight::WRAP_DEFAULT:highlight::WRAP_DISABLED;
}

string HighlightFrame::analyzeFile(const string& file){
    ifstream inFile(file.c_str());
    string firstLine;
    getline (inFile, firstLine);
    StringMap::iterator it;
     for (it=shebangs.begin(); it!=shebangs.end();it++){
       if (Pattern::matches(it->first, firstLine)) return it->second;
     }
    return "";
}

string HighlightFrame::getFileType(const string& suffix, const string &inputFile)
{
    string lcSuffix = StringTools::change_case(suffix);
    string fileType = (extensions.count(lcSuffix)) ? extensions[lcSuffix] : lcSuffix ;
    if (!fileType.empty()) return fileType;
    return analyzeFile(inputFile);
}

string HighlightFrame::getFileSuffix(const string& fileName)
{
  unsigned int ptPos=fileName.rfind(".");
  return (ptPos == string::npos) ? "" : fileName.substr(ptPos+1,
                                        fileName.length());
}

string HighlightFrame::getOutFileSuffix(){
  switch (outputFormatChoice->GetSelection()) {
    case 0: return ".html";
    case 1: return ".xhtml";
    case 2:
    case 3: return ".tex";
    case 4: return ".rtf";
    case 5: return ".svg";
    case 6: return ".xml";
  }
  return ".html";
}

highlight::OutputType HighlightFrame::getOutputType(){
    switch (outputFormatChoice->GetSelection()){
     case 0: return highlight::HTML;
     case 1: return highlight::XHTML;
     case 2: return highlight::LATEX;
     case 3: return highlight::TEX;
     case 4: return highlight::RTF;
     case 5: return highlight::SVG;
     case 6: return highlight::XML;
    }
    return highlight::HTML;
}

void HighlightFrame::updatePreview(){
    wxArrayInt selections;
    listBox->GetSelections(selections);
    if (!selections.GetCount()) return;

    int x=0, y=0;
    preview-> GetViewStart(&x, &y);
    wxBeginBusyCursor();
    SetStatusText(fcStrings->Read(("l044"), wxEmptyString),1);
    highlight::Html32Generator pwgenerator;

    applyCtrlValues(&pwgenerator, true);
    pwgenerator.setMaxInputLineCnt(500);

    // dont't change Font when teX or laTeX is selected
    if(!cbCustomFont->GetValue()||outputFormatChoice->GetSelection()==2 ||
        outputFormatChoice->GetSelection()==3){
      pwgenerator.setBaseFont("Times");
      pwgenerator.setBaseFont("10");
    } else {
      pwgenerator.setBaseFont(fontFace->GetValue());
      pwgenerator.setBaseFontSize(fontSize->GetValue());
    }
    wxString previewData;
    wxString currentInputFile= listBox->GetString(selections.Item(0));
    string suffix = getFileType(getFileSuffix(currentInputFile), currentInputFile);
    string langDefPath = dataDir.getLangPath() + suffix + ".lang";
    if (pwgenerator.initLanguage(langDefPath)!=highlight::LOAD_FAILED) {
          previewData = wxString(pwgenerator.generateStringFromFile(currentInputFile));
    }
    if (!previewData.IsEmpty()) {
        wxString pwLabel;
        pwLabel.Printf(fcStrings->Read(("l043"), wxEmptyString).c_str(), currentInputFile.c_str());
        lblPreview->SetLabel(pwLabel);
        preview->SetPage(previewData);
       // wxMessageBox(previewData);
    }
    wxEndBusyCursor();
    preview->Scroll( x, y);
    SetStatusText(fcStrings->Read(("l024"), wxEmptyString),1);
}

#ifndef __WXMAC__
bool DropFiles::OnDropFiles (wxCoord x, wxCoord y, const wxArrayString& filenames) {
  for (size_t n = 0; n < filenames.Count(); n++) {
    if (wxFileName(filenames[n]).IsDir()) {
        wxMessageBox (("Directories are not allowed!"),
                      ("Error"), wxOK | wxICON_EXCLAMATION);
        return false;
    }
  }
  m_frame->addInputFiles(filenames, "", false);
  return true;
}
#endif
