/***************************************************************************
                          kdrawchem.cpp  -  description
                             -------------------
    begin                : Mon Jul 15 12:24:12 CDT 2002
    copyright            : (C) 2002 by Adam Tenderholt
    email                : a-tenderholt@northwestern.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 files for QT
#include <qdir.h>
#include <qprinter.h>
#include <qpainter.h>
#include <qfontdatabase.h>
#include <qstringlist.h>
#include <qstring.h>

// include files for KDE
#include <kaction.h>
#include <kiconloader.h>
#include <kmenubar.h>
#include <kstatusbar.h>
#include <klocale.h>
#include <kconfig.h>
#include <kstdaction.h>
#include <kpopupmenu.h>
#include <kshortcut.h>
#include <kdebug.h>


// application specific includes
#include "kdrawchem.h"
#include "kdrawchemview.h"
#include "kdrawchemdoc.h"
#include "xdc_event.h"
#include "arrows.h"  //contains xpms for arrows
#include "brackets.h"  //contains xpms for brackets
#include "symbol_xpm.h" //contains xpms for symbols
#include "font_xpm.h"
#include "tool_xpm.h"
#include "curve_xpm.h"
#include "sugar_xpm.h"
#include "na_xpm.h"
#include "aa_xpm.h"
#include "ring_xpm.h"

//OBLib includes
//#include <data.h>
//#include <obutil.h>

QString RingDir(RINGHOME);

Preferences preferences;

class KPopupMenu;
#define ID_STATUS_MSG 1

IOIface KDrawChemApp::interface=IOIface();

KDrawChemApp::KDrawChemApp(QWidget* , const char* name):KMainWindow(0, name)
{
  config=kapp->config();
  m_rings=new CustomRings;
  m_rings->load();

  ///////////////////////////////////////////////////////////////////
  // call inits to invoke all other construction parts
  initStatusBar();
  initActions();
  initDocument();
  initView();

  readOptions();

  ///////////////////////////////////////////////////////////////////
  // disable actions at startup
  fileSave->setEnabled(false);
  fileSaveAs->setEnabled(false);
  filePrint->setEnabled(true);
  editCut->setEnabled(false);
  editCopy->setEnabled(false);
  editPaste->setEnabled(false);
  KDChemFilter=i18n("*.xdc|Native XDrawChem format (*.xdc)\n*.cml|Chemical Markup Language (*.cml)\n*.mol|MDL Molfile (*.mol)\n*|All files (*)");

}

KDrawChemApp::~KDrawChemApp()
{
  std::cerr << "Destroying KDrawChemApp" << std::endl;

  if(m_rings) {
    std::cerr << "Saving rings" << std::endl;
    m_rings->save();
    delete m_rings;
  }
}

void KDrawChemApp::initActions()
{
  fileNewWindow = new KAction(i18n("New &Window"), 0, 0, this, SLOT(slotFileNewWindow()), actionCollection(),"file_new_window");
  fileNew = KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection());
  fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
  fileImport = new KAction(i18n("&Import..."),0,this,SLOT(slotFileImport()),actionCollection(),"file_import");
  fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
  fileSave = KStdAction::save(this, SLOT(slotFileSave()), actionCollection());
  fileSaveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
  savePicture = new KAction(i18n("Save picture..."),0,this,SLOT(slotSavePicture()),actionCollection(),"save_picture");
  fileClose = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
  filePrint = KStdAction::print(this, SLOT(slotFilePrint()), actionCollection());
  fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
  editCut = KStdAction::cut(this, SLOT(slotEditCut()), actionCollection());
  editCopy = KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection());
  editPaste = KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection());
  editUndo = KStdAction::undo(this,SLOT(slotEditUndo()),actionCollection());
  editSelectAll = new KAction(i18n("Select &All"),KShortcut("Ctrl+A"),this,SLOT(slotSelectAll()),actionCollection(),"select_all");
  editDelete = new KAction(i18n("&Delete"),KShortcut("Delete"),this,SLOT(slotDelete()),actionCollection(),"edit_delete");

  rotateMenu = new KActionMenu(i18n("Rotate"),actionCollection(),"rotate_menu");
  rotate90 = new KAction(i18n("Rotate 90 degrees"),0,this,SLOT(slotRotate90()),actionCollection(),0);
  rotate180 = new KAction(i18n("Rotate 180 degrees"),0,this,SLOT(slotRotate180()),actionCollection(),0);
  rotate270 = new KAction(i18n("Rotate 270 degrees"),0,this,SLOT(slotRotate270()),actionCollection(),0);

  rotateMenu->insert(rotate90);
  rotateMenu->insert(rotate180);
  rotateMenu->insert(rotate270);

  flipMenu = new KActionMenu(i18n("Flip"),actionCollection(),"flip_menu");
  flipH = new KAction(i18n("Flip Horizontal"),0,this,SLOT(slotFlipH()),actionCollection(),0);
  flipV = new KAction(i18n("Flip Vertical"),0,this,SLOT(slotFlipV()),actionCollection(),0);

  flipMenu->insert(flipH);
  flipMenu->insert(flipV);

  viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection());
  viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());

  fixedBond = new KToggleAction(i18n("Bond - fixed angle and length"),0,this,SLOT(toggleFixedBondLength()),actionCollection(),"fixed_bond");
  fixedBond->setChecked(true);
  preferences.setBond_fixed(true);

  fixedArrow = new KToggleAction(i18n("Arrow - fixed angle and length"),0,this,SLOT(toggleFixedArrowLength()),actionCollection(),"fixed_arrow");
  fixedArrow->setChecked(true);
  preferences.setArrow_fixed(true);
  backgroundColor = new KAction(i18n("Set background color..."),  0,  this,
                                SLOT(slotSetBackgroundColor()),  actionCollection(),
                                "background_color");

  fixedDialog = new KAction(i18n("Dra&wing settings..."), 0, this, SLOT(slotShowFixedDialog()),
              actionCollection(),  "fixed_dialog");


  toolsCalcMW = new KAction(i18n("Calculate Molecular Weight"),0,this,SLOT(calcMW()),actionCollection(),"calc_MW");
  toolsCalcEF = new KAction(i18n("Calculate Empirical Formula"),0,this,SLOT(calcEmpiricalFormula()),actionCollection(),"calc_EF");
  toolsCalcEA = new KAction(i18n("Calculate Elemental Analysis..."),0,this,SLOT(calcElementalAnalysis()),actionCollection(),"calc_EA");
  toolsCalcMI = new KAction(i18n("Molecular Information..."),0,this,SLOT(calcMolecularInfo()),actionCollection(),"calc_MI");
  toolsCalc13CNMR = new KAction(i18n("Predict 13C NMR..."),0,this,SLOT(calc13CNMR()),actionCollection(),"calc_13CNMR");
  toolsCalc1HNMR = new KAction(i18n("Predict 1H NMR..."),0,this,SLOT(calc1HNMR()),actionCollection(),"calc_1HNMR");
  toolsCalcIR = new KAction(i18n("Predict IR..."),0,this,SLOT(calcIR()),actionCollection(),"calc_IR");
  toolsCleanupStruct = new KAction(i18n("Cleanup Structure"),0,this,SLOT(cleanupStruct()),actionCollection(),"cleanup_struct");
  toolsInputSMILES = new KAction( i18n( "Input SMILES..." ), 0, this, SLOT( inputSMILES() ), actionCollection(), "input_smiles" );
  toolsOutputSMILES = new KAction( i18n( "Output SMILES" ), 0, this, SLOT( outputSMILES() ), actionCollection(), "output_smiles" );

  //sets the tools
  setModeSelect = new KAction(i18n("Select"),QIconSet(QPixmap(selecttool)),0,this,SLOT(setMode_Select()),actionCollection(),"set_mode_select");
  setModeErase = new KAction(i18n("Erase"),QIconSet(QPixmap(erasetool)),0,this,SLOT(setMode_Erase()),actionCollection(),"set_mode_erase");
  setModeDrawLine = new KAction(i18n("Draw line"),QIconSet(QPixmap(linetool)),0,this,SLOT(setMode_DrawLine()),actionCollection(),"set_mode_draw");
  setModeDrawDashLine = new KAction(i18n("Draw dashed line"),QIconSet(QPixmap(dashtool)),0,this,SLOT(setMode_DrawDashLine()),actionCollection(),"set_mode_drawdash");
  setModeDrawUpLine = new KAction(i18n("Draw line up"),QIconSet(QPixmap(uptool)),0,this,SLOT(setMode_DrawLineUp()),actionCollection(),"set_mode_drawup");
  setModeDrawDownLine = new KAction(i18n("Draw line down"),QIconSet(QPixmap(downtool)),0,this,SLOT(setMode_DrawLineDown()),actionCollection(),"set_mode_drawdown");
  setModeDrawText = new KAction(i18n("Text"),QIconSet(QPixmap(texttool)),0,this,SLOT(setMode_DrawText()),actionCollection(),"set_mode_drawtext");

  //creates the entries to the arrow menu
  arrowRegular = new KToolBarPopupAction(KGuiItem(i18n( "Regular" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_DrawArrow()),actionCollection(),"arrow_regular");
  arrowDash = new KToolBarPopupAction(KGuiItem(i18n( "Dashed" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_DrawArrowDash()),actionCollection(),"arrow_dash");
  arrowBI1 = new KToolBarPopupAction(KGuiItem(i18n("BI1" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_DrawArrowBI1()),actionCollection(),"arrow_bi1");
  arrowBI2 = new KToolBarPopupAction(KGuiItem(i18n( "BI2" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_DrawArrowBI2()),actionCollection(),"arrow_bi2");
  arrowRetro = new KToolBarPopupAction(KGuiItem(i18n( "Retro" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_DrawArrowRetro()),actionCollection(),"arrow_retro");

  //adds icons to the arrow menu
  arrowRegular->setIconSet(QIconSet(QPixmap(arrow_regular_xpm)));
  arrowDash->setIconSet(QIconSet(QPixmap(arrow_dash_xpm)));
  arrowBI1->setIconSet(QIconSet(QPixmap(arrow_bi1_xpm)));
  arrowBI2->setIconSet(QIconSet(QPixmap(arrow_bi2_xpm)));
  arrowRetro->setIconSet(QIconSet(QPixmap(arrow_retro_xpm)));

  //populates the arrow menu
  arrowMenu = new KActionMenu(i18n("Arrow Menu"), QIconSet(QPixmap(arrow_regular_xpm)), actionCollection(),"arrow_menu");
  arrowMenu->insert(arrowRegular,0);
  arrowMenu->insert(arrowDash,1);
  arrowMenu->insert(arrowBI1,2);
  arrowMenu->insert(arrowBI2,3);
  arrowMenu->insert(arrowRetro,4);

  //sets the current arrow to the regular arrow, and connects so that allows the arrowMenu icon to change
  currentArrow=0;
  connect(arrowMenu,SIGNAL(activated()),this,SLOT(slotArrowMenuClicked()));

  //creates the entries to the curve arrow menu
  curve90CW = new KToolBarPopupAction(KGuiItem(i18n( "90 CW" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_Curve90CW()),actionCollection(),"curve90cw");
  curve90CCW = new KToolBarPopupAction(KGuiItem(i18n( "90 CCW" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_Curve90CCW()),actionCollection(),"curve90ccw");
  curve180CW = new KToolBarPopupAction(KGuiItem(i18n("180 CW" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_Curve180CW()),actionCollection(),"curve180cw");
  curve180CCW = new KToolBarPopupAction(KGuiItem(i18n( "180 CCW" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_Curve180CCW()),actionCollection(),"curve180ccw");
  curve270CW = new KToolBarPopupAction(KGuiItem(i18n( "270 CW" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_Curve270CW()),actionCollection(),"curve270cw");
  curve270CCW = new KToolBarPopupAction(KGuiItem(i18n( "270 CCW" ),QIconSet(QPixmap(arrow_regular_xpm))),0,this,SLOT(setMode_Curve270CCW()),actionCollection(),"curve270ccw");

  //adds icons to the curve arrow menu
  curve90CW->setIconSet(QIconSet(QPixmap(cw90_xpm)));
  curve90CCW->setIconSet(QIconSet(QPixmap(ccw90_xpm)));
  curve180CW->setIconSet(QIconSet(QPixmap(cw180_xpm)));
  curve180CCW->setIconSet(QIconSet(QPixmap(ccw180_xpm)));
  curve270CW->setIconSet(QIconSet(QPixmap(cw270_xpm)));
  curve270CCW->setIconSet(QIconSet(QPixmap(ccw270_xpm)));

  //populates the curve arrow menu
  curveArrowMenu = new KActionMenu(i18n("Curve Arrow Menu"), QIconSet(QPixmap(cw90_xpm)), actionCollection(),"curve_arrow_menu");
  curveArrowMenu->insert(curve90CW,0);
  curveArrowMenu->insert(curve90CCW,1);
  curveArrowMenu->insert(curve180CW,2);
  curveArrowMenu->insert(curve180CCW,3);
  curveArrowMenu->insert(curve270CW,4);
  curveArrowMenu->insert(curve270CCW,5);

  //sets the current curve arrow to the 90CW arrow, and connects so that allows the curveArrowMenu icon to change
  currentCurveArrow=0;
  connect(curveArrowMenu,SIGNAL(activated()),this,SLOT(slotCurveArrowMenuClicked()));

  bracketSquare = new KToolBarPopupAction(KGuiItem(i18n( "Square Bracket" ),QIconSet(QPixmap(squarebracket_xpm))),0,this,SLOT(setMode_DrawBracketSquare()),actionCollection(),"bracket_square");
  bracketCurve = new KToolBarPopupAction(KGuiItem(i18n( "Curve Bracket" ),QIconSet(QPixmap(curvebracket_xpm))),0,this,SLOT(setMode_DrawBracketCurve()),actionCollection(),"bracket_curve");
  bracketBrace = new KToolBarPopupAction(KGuiItem(i18n( "Brace Bracket" ),QIconSet(QPixmap(bracebracket_xpm))),0,this,SLOT(setMode_DrawBracketBrace()),actionCollection(),"bracket_brace");

  bracketSquare->setIconSet(QIconSet(QPixmap(squarebracket_xpm)));
  bracketCurve->setIconSet(QIconSet(QPixmap(curvebracket_xpm)));
  bracketBrace->setIconSet(QIconSet(QPixmap(bracebracket_xpm)));

  bracketMenu = new KActionMenu(i18n("Bracket Menu"), QIconSet(QPixmap(squarebracket_xpm)),actionCollection(),"bracket_menu");
  bracketMenu->insert(bracketSquare,0);
  bracketMenu->insert(bracketCurve,1);
  bracketMenu->insert(bracketBrace,2);

  currentBracket=0;
  connect(bracketMenu,SIGNAL(activated()),this,SLOT(slotBracketMenuClicked()));

  initSymbolActions();

  fontAction = new KFontAction( i18n( "Set Font Family" ), 0, actionCollection(), "font_action" );
  //fontAction->setComboWidth(55);
  fontAction->popupMenu()->setFixedWidth(220);
  connect(fontAction, SIGNAL(activated(const QString&)), SLOT(setFontFamily(const QString&)) );
  fontAction->setFont("Helvetica");

  fontSize = new KFontSizeAction(i18n("Set Font Size"),0,actionCollection(),"font_size");
  connect(fontSize,SIGNAL(fontSizeChanged(int)),this,SLOT(setFontSize(int)));
  //fontSize->setComboWidth(20);
  fontSize->setFontSize(12);

  setBold = new KToggleAction(i18n("Bold"),QPixmap(boldtool_xpm),KKey("Ctrl+KEY_B"),this,SLOT(toggleFontBold()),actionCollection(),"bold");
  setItalic = new KToggleAction(i18n("Italic"),QPixmap(italictool_xpm),KKey("Ctrl-I"),this,SLOT(toggleFontItalic()),actionCollection(),"italic");
  setUnderline = new KToggleAction(i18n("Underline"),QPixmap(underlinetool_xpm),KKey("Ctrl-U"),this,SLOT(toggleFontUnderline()),actionCollection(),"underline");
  setSuperscript = new KToggleAction(i18n("Superscript"),QPixmap(superscript_xpm),KKey("Ctrl-+"),this,SLOT(toggleFontSuperscript()),actionCollection(),"superscript");
  setSubscript = new KToggleAction(i18n("Subscript"),QPixmap(subscript_xpm),KKey("Ctrl--"),this,SLOT(toggleFontSubscript()),actionCollection(),"subscript");

  setBold->setExclusiveGroup("font_options");
  setItalic->setExclusiveGroup("font_options");
  setUnderline->setExclusiveGroup("font_options");
  setSuperscript->setExclusiveGroup("font_options");
  setSubscript->setExclusiveGroup("font_options");

  ringsMenu = new KActionMenu(i18n("Rings"),QIconSet(QPixmap(ringtool)),actionCollection(),"rings_menu");

  //sugarMenu = new KActionMenu(i18n("Sugars"),this,"sugar_menu");
  //ringsMenu->insert(sugarMenu);

  fileNewWindow->setStatusText(i18n("Opens a new application window"));
  fileNew->setStatusText(i18n("Creates a new document"));
  fileOpen->setStatusText(i18n("Opens an existing document"));
  fileOpenRecent->setStatusText(i18n("Opens a recently used file"));
  fileSave->setStatusText(i18n("Saves the actual document"));
  fileSaveAs->setStatusText(i18n("Saves the actual document as..."));
  fileClose->setStatusText(i18n("Closes the actual document"));
  filePrint ->setStatusText(i18n("Prints out the actual document"));
  fileQuit->setStatusText(i18n("Quits the application"));
  editCut->setStatusText(i18n("Cuts the selected section and puts it to the clipboard"));
  editCopy->setStatusText(i18n("Copies the selected section to the clipboard"));
  editPaste->setStatusText(i18n("Pastes the clipboard contents to actual position"));
  viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
  viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));

  // use the absolute path to your kdrawchemui.rc file for testing purpose in createGUI();
  //createGUI("/home/adam/kemistry/kdrawchem/kdrawchemui.rc");
  createGUI();

  initRingsActions();


}

void KDrawChemApp::initRingsActions()
{
      ringsPopupMenu=ringsMenu->popupMenu();
  sugarMenu=new KPopupMenu;
  nucleicMenu=new KPopupMenu;
	aminoMenu=new KPopupMenu;
  ringMenu=new KPopupMenu;
	groupMenu=new KPopupMenu;
  customMenu=new KPopupMenu;

  ringsPopupMenu->insertItem(i18n("Rings"),ringMenu);
  ringMenu->insertItem(QIconSet(QPixmap(r_cyclopropane),QIconSet::Small),i18n("Cyclopropane"),0);
  ringMenu->insertItem(QIconSet(QPixmap(r_cyclobutane),QIconSet::Small),i18n("Cyclobutane"),1);
  ringMenu->insertItem(QIconSet(QPixmap(r_cyclopentane),QIconSet::Small),i18n("Cyclopentane"),2);
  ringMenu->insertItem(QIconSet(QPixmap(r_6flat),QIconSet::Small),i18n("Cyclohexane (flat)"),3);
  ringMenu->insertItem(QIconSet(QPixmap(r_6chair),QIconSet::Small),i18n("Cyclohexane (chair)"),4);
  ringMenu->insertItem(QIconSet(QPixmap(r_6boat),QIconSet::Small),i18n("Cyclohexane (boat)"),5);
  ringMenu->insertItem(QIconSet(QPixmap(ring7),QIconSet::Small),i18n("Cycloheptane"),6);
  ringMenu->insertItem(QIconSet(QPixmap(ring8),QIconSet::Small),i18n("Cyclooctane"),7);

  ringMenu->insertItem(QIconSet(QPixmap(r_cyclopentadiene),QIconSet::Small),i18n("Cyclopentadiene"),8);
  ringMenu->insertItem(QIconSet(QPixmap(r_benzene),QIconSet::Small),i18n("Benzene"),9);
  ringMenu->insertItem(QIconSet(QPixmap(naphthalene_xpm),QIconSet::Small),i18n("Naphthalene"),10);
  ringMenu->insertItem(QIconSet(QPixmap(anthracene_xpm),QIconSet::Small),i18n("Anthracene"),11);
  ringMenu->insertItem(QIconSet(QPixmap(biphenyl_xpm),QIconSet::Small),i18n("Biphenyl"),12);

  ringMenu->insertItem(QIconSet(QPixmap(r_imidazole),QIconSet::Small),i18n("Imidazole"),13);
  ringMenu->insertItem(QIconSet(QPixmap(r_indole),QIconSet::Small),i18n("Indole"),14);
  ringMenu->insertItem(QIconSet(QPixmap(r_purine),QIconSet::Small),i18n("Purine"),15);
  ringMenu->insertItem(QIconSet(QPixmap(r_pyrimidine),QIconSet::Small),i18n("Pyrimidine"),16);

  ringMenu->insertItem(QIconSet(QPixmap(r_steroid),QIconSet::Small),i18n("Steroid"),17);

  ringsPopupMenu->insertItem(i18n("Sugars"),sugarMenu);
  sugarMenu->insertItem(QIconSet(QPixmap(s_ribose),QIconSet::Small),i18n("Ribose"),0);
  sugarMenu->insertItem(QIconSet(QPixmap(s_deoxyribose),QIconSet::Small),i18n("Deoxyribose"),1);
  sugarMenu->insertItem(QIconSet(QPixmap(s_d_fructose),QIconSet::Small),i18n("D-fructose"),2);
  sugarMenu->insertItem(QIconSet(QPixmap(s_d_glucose),QIconSet::Small),i18n("D-glucose"),3);

  ringsPopupMenu->insertItem(i18n("Nucleic Acids"),nucleicMenu);
  nucleicMenu->insertItem(QIconSet(QPixmap(na_adenine),QIconSet::Small),i18n("Adenine"),0);
  nucleicMenu->insertItem(QIconSet(QPixmap(na_cytosine),QIconSet::Small),i18n("Cytosine"),1);
  nucleicMenu->insertItem(QIconSet(QPixmap(na_guanine),QIconSet::Small),i18n("Guanine"),2);
  nucleicMenu->insertItem(QIconSet(QPixmap(na_thymine),QIconSet::Small),i18n("Thymine"),3);
  nucleicMenu->insertItem(QIconSet(QPixmap(na_uracil),QIconSet::Small),i18n("Uracil"),4);

	ringsPopupMenu->insertItem(i18n("Amino Acids"),aminoMenu);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_ala),QIconSet::Small),i18n("Alanine"),0);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_arg),QIconSet::Small),i18n("Arginine"),1);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_asn),QIconSet::Small),i18n("Asparagine"),2);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_asp),QIconSet::Small),i18n("Aspartic Acid"),3);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_cys),QIconSet::Small),i18n("Cysteine"),4);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_gln),QIconSet::Small),i18n("Glutamine"),5);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_glu),QIconSet::Small),i18n("Glutamic Acid"),6);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_gly),QIconSet::Small),i18n("Glycine"),7);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_his),QIconSet::Small),i18n("Histidine"),8);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_ile),QIconSet::Small),i18n("Isoleucine"),9);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_leu),QIconSet::Small),i18n("Leucine"),10);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_lys),QIconSet::Small),i18n("Lysine"),11);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_met),QIconSet::Small),i18n("Methionine"),12);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_phe),QIconSet::Small),i18n("Phenyalanine"),13);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_pro),QIconSet::Small),i18n("Proline"),14);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_ser),QIconSet::Small),i18n("Serine"),15);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_thr),QIconSet::Small),i18n("Threonine"),16);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_trp),QIconSet::Small),i18n("Tryptophan"),17);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_tyr),QIconSet::Small),i18n("Tyrosine"),18);
	aminoMenu->insertItem(QIconSet(QPixmap(aa_val),QIconSet::Small),i18n("Valine"),19);

	ringsPopupMenu->insertItem(i18n("Useful groups"),groupMenu);
	groupMenu->insertItem(i18n("FMOC"),0);
	groupMenu->insertItem(i18n("BOC"),1);
	groupMenu->insertItem(i18n("DABCYL"),2);
	groupMenu->insertItem(i18n("DABSYL"),3);
	groupMenu->insertItem(i18n("DANSYL"),4);
	groupMenu->insertItem(i18n("EDANS"),5);

  ringsPopupMenu->insertItem(i18n("Custom"),customMenu);
  customMenu->insertItem(i18n("Add entry..."),0);
  customMenu->insertSeparator(1);

  for(int i=0;i<m_rings->size();i++) {
    customMenu->insertItem(m_rings->getTitle(i),i+1);
  }

  connect(ringMenu,SIGNAL(activated(int)),this,SLOT(slotRing(int)));
  connect(sugarMenu,SIGNAL(activated(int)),this,SLOT(slotSugar(int)));
  connect(nucleicMenu,SIGNAL(activated(int)),this,SLOT(slotNucleic(int)));
	connect(aminoMenu,SIGNAL(activated(int)),this,SLOT(slotAmino(int)));
	connect(groupMenu,SIGNAL(activated(int)),this,SLOT(slotGroup(int)));
  connect(customMenu,SIGNAL(activated(int)),this,SLOT(slotCustom(int)));
}

void KDrawChemApp::initStatusBar()
{
  ///////////////////////////////////////////////////////////////////
  // STATUSBAR
  // TODO: add your own items you need for displaying current application status.
  statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
}

void KDrawChemApp::initDocument()
{
  doc = new KDrawChemDoc(this);
  doc->newDocument();
  _clipboard = new Clipboard();
  doc->setClipboard(_clipboard);
  doc->setCustomRings(m_rings);
  //dialog = new KFileDialog(QDir::currentDirPath(),KDChemFilter,this,"file_dia",false);
  //dialog = new KFileDialog(QDir::currentDirPath(),KDChemFilter,this,"file_dia",false);
  //dialog->setMode(KFileDialog::Saving);
//  connect(dialog,SIGNAL(filterChanged(const QString&)),doc,SLOT(slotFilterChanged(const QString&)));
  dialog=0;
}

void KDrawChemApp::initView()
{
  ////////////////////////////////////////////////////////////////////
  // create the main widget here that is managed by KTMainWindow's view-region and
  // connect the widget to your document to display document contents.

  view = new KDrawChemView(this);
  doc->addView(view);
  view->setCustomRings(m_rings);
  setCentralWidget(view);
  setCaption(doc->URL().fileName(),false);
  connect(view,SIGNAL(signalModified()),doc,SLOT(slotModified()));
  connect(view,SIGNAL(signalModified()),this,SLOT(slotModified()));

  connect(view,SIGNAL(SignalSetStatusBar(QString)),this,SLOT(slotStatusMsg(QString)));
  connect(view,SIGNAL(hasBold(bool)),this,SLOT(slotHasBold(bool)));
  connect(view,SIGNAL(hasItalic(bool)),this,SLOT(slotHasBold(bool)));
  connect(view,SIGNAL(hasUnderline(bool)),this,SLOT(slotHasUnderline(bool)));
  connect(view,SIGNAL(hasSuperscript(bool)),this,SLOT(slotHasSuperscript(bool)));
  connect(view,SIGNAL(hasSubscript(bool)),this,SLOT(slotHasSubscript(bool)));
  connect(view,SIGNAL(signalFont(QString)),this,SLOT(slotFont(QString)));
  connect(view,SIGNAL(signalFontSize(int)),this,SLOT(slotFontSize(int)));
  connect(view,SIGNAL(signalNewRingsSize(int)),this,SLOT(slotNewRingsSize(int)));

  connect(view,SIGNAL(XDCEventSignal(XDC_Event*)), doc,
          SLOT(XDCEventHandler(XDC_Event*)));
}

void KDrawChemApp::openDocumentFile(const KURL& url)
{
  slotStatusMsg(i18n("Opening file..."));

  doc->openDocument( url);
  fileOpenRecent->addURL( url );
  filePrint->setEnabled(true);
  slotStatusMsg(i18n("Ready."));
}


KDrawChemDoc *KDrawChemApp::getDocument() const
{
  return doc;
}

void KDrawChemApp::saveOptions()
{
  config->setGroup("General Options");
  config->writeEntry("Geometry", size());
  config->writeEntry("Show Toolbar", viewToolBar->isChecked());
  config->writeEntry("Show Statusbar",viewStatusBar->isChecked());
  config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
  fileOpenRecent->saveEntries(config,"Recent Files");

  config->setGroup("Drawing settings");
//write fied arrow preferences
  config->writeEntry("Fixed arrow",  preferences.getArrow_fixed());
  config->writeEntry("Fixed arrow length",  preferences.getArrow_fixedlength());
  config->writeEntry("Fixed arrow angle",  preferences.getArrow_fixedangle());
  //write fixed bond preferences
  config->writeEntry("Fixed bond",  preferences.getBond_fixed());
  config->writeEntry("Fixed bond length",  preferences.getBond_fixedlength());
  config->writeEntry("Fixed bond angle",  preferences.getBond_fixedangle());
  //write double bond offset
  config->writeEntry("Double bond offset",  preferences.getDoubleBondOffset());

}


void KDrawChemApp::readOptions()
{

  config->setGroup("General Options");

  // bar status settings
  bool bViewToolbar = config->readBoolEntry("Show Toolbar", true);
  viewToolBar->setChecked(bViewToolbar);
  slotViewToolBar();

  bool bViewStatusbar = config->readBoolEntry("Show Statusbar", true);
  viewStatusBar->setChecked(bViewStatusbar);
  slotViewStatusBar();


  // bar position settings
  KToolBar::BarPosition toolBarPos;
  toolBarPos=(KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top);
  toolBar("mainToolBar")->setBarPos(toolBarPos);

  // initialize the recent file list
  fileOpenRecent->loadEntries(config,"Recent Files");

  QSize size=config->readSizeEntry("Geometry");
  if(!size.isEmpty())
  {
    resize(size);
  }

  //read preferences
  config->setGroup("Drawing settings");
  //read double bond offset
  preferences.setDoubleBondOffset(config->readDoubleNumEntry("Double bond offset",  2.0));
  //read fixed arrow settings
  preferences.setArrow_fixed(config->readBoolEntry("Fixed arrow", true));
  fixedArrow->setChecked(preferences.getArrow_fixed());
  preferences.setArrow_fixedlength(config->readDoubleNumEntry("Fixed arrow length",  50.0));
  preferences.setArrow_fixedangle(config->readDoubleNumEntry("Fixed arrow angle", 15.0));
  //read fixed bond settings
  preferences.setBond_fixed(config->readBoolEntry("Fixed bond", true));
  fixedBond->setChecked(preferences.getBond_fixed());
  preferences.setBond_fixedlength(config->readDoubleNumEntry("Fixed bond length",  25.0));
  preferences.setBond_fixedangle(config->readDoubleNumEntry("Fixed bond angle", 15.0));


}

void KDrawChemApp::saveProperties(KConfig *_cfg)
{
  if(doc->URL().fileName()!=i18n("Untitled") && !doc->isModified())
  {
    // saving to tempfile not necessary

  }
  else
  {
    KURL url=doc->URL();
    _cfg->writeEntry("filename", url.url());
    _cfg->writeEntry("modified", doc->isModified());
    QString tempname = kapp->tempSaveName(url.url());
    QString tempurl= KURL::encode_string(tempname);
    KURL _url(tempurl);
    doc->saveDocument(_url);
  }
}


void KDrawChemApp::readProperties(KConfig* _cfg)
{
  QString filename = _cfg->readEntry("filename", "");
  KURL url(filename);
  bool modified = _cfg->readBoolEntry("modified", false);
  if(modified)
  {
    bool canRecover;
    QString tempname = kapp->checkRecoverFile(filename, canRecover);
    KURL _url(tempname);

    if(canRecover)
    {
      doc->openDocument(_url);
      doc->setModified();
      setCaption(_url.fileName(),true);
      QFile::remove(tempname);
    }
  }
  else
  {
    if(!filename.isEmpty())
    {
      doc->openDocument(url);
      setCaption(url.fileName(),false);
    }
  }
}

bool KDrawChemApp::queryClose()
{
  return doc->saveModified();
}

bool KDrawChemApp::queryExit()
{
  saveOptions();
  return true;
}


void KDrawChemApp::initSymbolActions()
{
    kdDebug() << "KDrawChemApp::initSymbolActions()" << endl;

    symbolMenu = new KActionMenu(i18n("Symbol Menu"), QIconSet(QPixmap(sym_plus_xpm)),
                               actionCollection(),"symbol_menu");
    KToolBarPopupAction *tempAction = new KToolBarPopupAction(KGuiItem(i18n( "Positive" ), QIconSet(QPixmap(sym_plus_xpm))),0, this, SLOT(setMode_DrawSymbolPlus()),actionCollection(), "symbol_plus");
    tempAction->setIconSet(QIconSet(QPixmap(sym_plus_xpm)));
    symbolMenu->insert(tempAction,0);
    tempAction = new KToolBarPopupAction(KGuiItem(i18n( "Negative" ), QIconSet(QPixmap(sym_minus_xpm))),0,this,SLOT(setMode_DrawSymbolMinus()),actionCollection(),"symbol_minus");
    tempAction->setIconSet(QIconSet(QPixmap(sym_minus_xpm)));
    symbolMenu->insert(tempAction,1);
  tempAction = new KToolBarPopupAction(KGuiItem(i18n( "Partial Positive" ),QIconSet(QPixmap(sym_delta_plus_xpm))),0,this,SLOT(setMode_DrawSymbolDeltaPlus()),actionCollection(),"symbol_delta_plus");
  tempAction->setIconSet(QIconSet(QPixmap(sym_delta_plus_xpm)));
  symbolMenu->insert(tempAction,2);
  tempAction = new KToolBarPopupAction(KGuiItem(i18n( "Partial Negative" ),QIconSet(QPixmap(sym_delta_minus_xpm))),0,this,SLOT(setMode_DrawSymbolDeltaMinus()),actionCollection(),"symbol_delta_minus");
  tempAction->setIconSet(QIconSet(QPixmap(sym_delta_minus_xpm)));
  symbolMenu->insert(tempAction,3);
  tempAction = new KToolBarPopupAction(KGuiItem(i18n( "One Electron" ),QIconSet(QPixmap(sym_1e_xpm))),0,this,SLOT(setMode_DrawTempAction()),actionCollection(),"symbol_one_electron");
  tempAction->setIconSet(QIconSet(QPixmap(sym_1e_xpm)));
  symbolMenu->insert(tempAction,4);
  tempAction = new KToolBarPopupAction(KGuiItem(i18n( "Two Electrons" ),QIconSet(QPixmap(sym_2e_xpm))),0,this,SLOT(setMode_DrawTempAction()),actionCollection(),"symbol_two_electrons");
  tempAction->setIconSet(QIconSet(QPixmap(sym_2e_xpm)));
  symbolMenu->insert(tempAction,5);
  tempAction = new KToolBarPopupAction(KGuiItem(i18n( "Bridged Ring" ),QIconSet(QPixmap(sym_ring_up_xpm))),0,this,SLOT(setMode_DrawSymbolRingUp()),actionCollection(),"symbol_bridged_ring");
  tempAction->setIconSet(QIconSet(QPixmap(sym_ring_up_xpm)));
  symbolMenu->insert(tempAction,6);
  tempAction = new KToolBarPopupAction(KGuiItem(i18n("p Orbital"), QIconSet(QPixmap(p_orbital_xpm))),  0,  this,  SLOT(setMode_DrawSymbolPOrbital()), actionCollection(), "symbol_p_orbital");
  tempAction->setIconSet(QIconSet(QPixmap(p_orbital_xpm)));
  symbolMenu->insert(tempAction,  7);

  currentSymbol=0;
  connect(symbolMenu,SIGNAL(activated()),this,SLOT(slotSymbolMenuClicked()));

}


#include "kdrawchem.moc"