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

#include "gui/SToolBar.h"

#include "gui/Main.h"
#include "swidget/SIconFactory.h"

SToolBarListener::SToolBarListener(void)
{
}

SToolBarListener::~SToolBarListener()
{
}
void
SToolBarListener::buttonEnter (void* src, int button)
{
}
void
SToolBarListener::buttonLeave (void* src, int button)
{
}

/**
 * a button panel is just a panel of buttons.
 */
SToolBar::SToolBar (const SProperties props) 
{
  currentEvent = (int) SD_PARSING_DONE;
  displayEvent = (int) SD_PARSING_DONE;

  iconUpdater = 0;
  xmanagerCludge = true;
  unsigned int i;
  listener = 0;
  modified = false;
  printing = false;
  editorLR = true;

  overrideLR = false;
  embedLR = false;
  currentLR = true;

  fonts = SStringVector (props["yudit.editor.fonts"]);

  if (fonts.size()==0) fonts.append ("default");
  fontsizes = SStringVector (props["yudit.editor.fontsizes"]);
  if (fontsizes.size()==0) fontsizes.append ("16");
  inputs = SStringVector (props["yudit.editor.inputs"]);
  buildDisplayInputs();
  if (inputs.size()==0) inputs.append ("straight");

  SString sf = props["yudit.editor.font"];
  currentFont = 0;
  for (i=0;i<fonts.size(); i++) if (sf == fonts[i]) break;
  if (i==fonts.size()) i=0; currentFont = i;

  currentInput = 0;
  SString si = props["yudit.editor.input"];
  for (i=0;i<inputs.size(); i++) if (si == inputs[i]) break;
  if (i==inputs.size()) i=0; currentInput = i;

  SString ss = props["yudit.editor.fontsize"];
  for (i=0;i<fontsizes.size(); i++) if (ss == fontsizes[i]) break;
  if (i==fontsizes.size()) i=0; currentFontSize = i;

  /* be int sync with SFormatIndex */
  paragraphBreaks.append (SS_LB_UNIX); 
  paragraphBreakStrings.append (translate ("Unix"));
  paragraphBreaks.append (SS_LB_DOS);
  paragraphBreakStrings.append (translate ("DOS"));
  paragraphBreaks.append (SS_LB_MAC);
  paragraphBreakStrings.append (translate ("MAC"));
  paragraphBreaks.append (SS_LB_PS);
  paragraphBreakStrings.append (translate ("PS"));
  currentParagraphSeparator = 0;
  currentEmbedding = SS_EmbedNone;

  /* create the buttons and set the preferred size */
  buttons[SS_OPEN] = new SButton (SIconFactory::getIcon("Open"), "O");
  buttons[SS_SAVE] = new SButton (SIconFactory::getIcon("SaveNotNeeded"), "S");
  buttons[SS_PRINT] = new SButton (SIconFactory::getIcon("Print"), "P");
  buttons[SS_PRINT_PREVIEW] = new SButton (SIconFactory::getIcon("Preview"), "W");
  buttons[SS_FIND] = new SButton (SIconFactory::getIcon("Find"), "Q"), 
  buttons[SS_GOTO] = new SButton (SIconFactory::getIcon("Goto"), "G"), 
  buttons[SS_UNDO] = new SButton (SIconFactory::getIcon("Undo"), "U");
  buttons[SS_REDO] = new SButton (SIconFactory::getIcon("Redo"), "R");
  buttons[SS_SET_OVERRIDE] = new SButton (SIconFactory::getIcon("RLO"), "D");

  buttons[SS_SET_EMBEDDING] = new SButton (SIconFactory::getIcon("RLE"), "E");
  buttons[SS_YIELD_EMBEDDING] = new SButton (SIconFactory::getIcon("LR"), "Y");
  buttons[SS_DOCUMENT_EMBEDDING] = new SButton (SIconFactory::getIcon("EmbedNone"), "T");

  buttons[SS_FONT] = new SButton ("", SIconFactory::getIcon("Font"));
  setFAccelerator (buttons[SS_FONT], fonts.size(), true);
  buttons[SS_INPUT] = new SButton ("", SIconFactory::getIcon("Right"));
  setFAccelerator (buttons[SS_INPUT], inputs.size(), false);
  buttons[SS_PARAGRAPH_BREAK] = new SButton ("", SIconFactory::getIcon("UNIX"));


  buttons[SS_MAGNIFY_PLUS] = new SButton (
       SIconFactory::getIcon("MagnifyPlus"), "Z");
  buttons[SS_MAGNIFY_MINUS] = new SButton (
       SIconFactory::getIcon("MagnifyMinus"), "A");
  buttons[SS_HIGHLIGHTING] = new SButton (
       SIconFactory::getIcon("DocumentXX"), "H");
  //b = new SButton (translate ("Cut(&X)"), SIconFactory::getIcon("Cut"));
  unsigned int p=0;
  unsigned int h=0;

  SColor fg = SColor(props["yudit.label.foreground"]);
  SColor tfg = SColor(props["yudit.title.foreground"]);

  SString font = props["yudit.default.font"];
  SString fontSizeString=props["yudit.default.fontsize"];

  double fontSize=0;
  fontSizeString.append ((char)0);
  sscanf (fontSizeString.array(), "%lf", &fontSize);
  if (fontSize < 2.0) fontSize = 2.0;


  for (i=0; i<(unsigned int) SS_MAX; i++)
  {
    buttons[i]->setFont(font, fontSize);
    buttons[i]->setForeground (tfg);
    buttons[i]->setButtonListener (this);

    SDimension wp;
    switch  (i)
    {
    case SS_PARAGRAPH_BREAK:
      wp = getMaxSize (buttons[i], paragraphBreakStrings, 
           paragraphBreakStrings[currentParagraphSeparator]);
      break;
    case SS_FONT:
      wp = getMaxSize (buttons[i], fonts, fonts[currentFont]);
      break;
/* too big.
    case SS_MAGNIFY_PLUS:
    case SS_MAGNIFY_MINUS:
      wp = getMaxSize (buttons[i], fontsizes);
      break;
*/
    case SS_INPUT:
      wp = getMaxSize (buttons[i], displayInputs, displayInputs[currentInput]);
      break;
    default:
      wp = buttons[i]->getPreferredSize();
    }
    buttons[i]->resize(wp);
    buttons[i]->move(SLocation ((int)p, wp.height));
    add (buttons[i]);
    p+= wp.width + 2;
    if (wp.height > h) h = wp.height;
  }

  for (i=0; i<(unsigned int) SS_MAX; i++)
  {
    buttons[i]->move(SLocation (buttons[i]->getLocation().x, (int)h));
  }

  preferredWidth = p;
  preferredSize = SDimension (p, 2*h);

  title = new SOpaqueLabel ("", SIconFactory::getIcon("Document"));
  title->setFont(font, fontSize);
  title->setForeground (fg);
  title->move (SLocation (0,0));
  title->resize (SDimension (p, h));

  titleEncoding = new SOpaqueLabel ("utf-8");
  titleEncoding->setFont(font, fontSize);
  titleEncoding->setForeground (fg);
  titleEncoding->move (SLocation (0,0));
  titleEncoding->resize (SDimension (p, h));

  tooltip = new SLabel ("", SIconFactory::getIcon("Help"));
  tooltip->setFont(font, fontSize);
  //tooltip->setForeground (fg);

  /* when the overall background will be set this will get screwed up a bit. */
  tooltip->setBackground (SColor("yellow").lighter());

  add (tooltip);
  tooltip->resize (SDimension (p, h));
  tooltip->move (SLocation (0, -2*(int)h));

  add (title);
  add (titleEncoding);
  iconUpdater = new SIconUpdater (window, title, 
        &currentEvent, &displayEvent);
  CHECK_NEW (iconUpdater);
}

/**
 * The inputs and currentInput has changed. Re-make menu
 */
void
SToolBar::inputChanged (const SStringVector& _inputs, unsigned int _current)
{
  SButton* cb = buttons[SS_INPUT];
  SDimension oldSize = cb->getSize();
  /* move all buttons */
  inputs = _inputs;
  currentInput = _current;
  buildDisplayInputs();
  
  SDimension wp = getMaxSize (cb, displayInputs, displayInputs[currentInput]);
  int delta = (int) wp.width - (int) oldSize.width;
  unsigned int i;
  if (delta != 0)
  {
    cb->resize (SDimension ((int)oldSize.width + delta, oldSize.height));
    for (i=1 + (unsigned int) SS_INPUT; i<(unsigned int) SS_MAX; i++)
    {
      buttons[i]->move(
         SLocation (buttons[i]->getLocation().x+delta, 
               buttons[i]->getLocation().y));
    }
  }
  cb->setText (displayInputs[currentInput]);
}

/**
 * To save display space we don't display the locale at
 * the end of the x-input-locale input methods.
 */
void
SToolBar::buildDisplayInputs()
{
  SStringVector plain; 
  for (unsigned i=0; i<inputs.size(); i++)
  {
    SString s = inputs[i];
    if (s.size()>2 && (s[0]=='x' || s[0]=='X') && s[1] == '-')
    {
      for (unsigned j=2; j<s.size(); j++)
      {
        if (s[j] == ':')
        {
          SString m = s;
          m.truncate (j);
          m.lower();
          /* This one will have the locale displayed */
          if (m=="x-utf-8") break;
          s.truncate (j);
          break;
        }
      }
    }
    plain.append (s); 
  }
  displayInputs  = plain;
}

SToolBar::~SToolBar ()
{
  if (iconUpdater) delete iconUpdater;
}

void
SToolBar::setHighlightName (const SString& _highlightName)
{
  // display only the last part.
  SStringVector v (_highlightName, ":", true);
  SString f = "";
  if (v.size() == 2)
  {
    f.append (v[0]);
    f.append (":");
    f.append (v[1]);
  }
  else if (v.size() == 1)
  {
    f.append (v[0]);
  }
  highlightName = f;
  
}

void
SToolBar::setFileName (const SString& _filename, const SString& _encoding) 
{
  window->redraw (true, title->getLocation().x, 
     title->getLocation().y, title->getSize().width, title->getSize().height);
  window->redraw (true, titleEncoding->getLocation().x, 
     titleEncoding->getLocation().y, titleEncoding->getSize().width, 
     titleEncoding->getSize().height);
  SString fn;
  //fn.append ("[");
  fn.append  (_encoding);
  //fn.append ("]");
  titleEncoding->setText (fn);
  
  title->setText (_filename);
  SDimension td = title->getPreferredSize();
  SDimension ted = titleEncoding->getPreferredSize();
  unsigned int sx = 
     (td.width + ted.width > getSize().width) 
        ? 0 : (getSize().width - td.width - ted.width)/2;
  //titleEncoding->move (SLocation (sx,0));
  titleEncoding->move (SLocation (0,0));
  titleEncoding->resize (SDimension (ted.width, td.height));

  title->move (SLocation (sx+(int)ted.width,0));
  title->resize (SDimension (td));

  window->redraw (true, title->getLocation().x, 
     title->getLocation().y, title->getSize().width, title->getSize().height);
  window->redraw (true, titleEncoding->getLocation().x, 
     titleEncoding->getLocation().y, titleEncoding->getSize().width, 
     titleEncoding->getSize().height);
}

void
SToolBar::resize(const SDimension & d)
{
  SPanel::resize(d);
  window->redraw (true, title->getLocation().x, 
     title->getLocation().y, title->getSize().width, title->getSize().height);
  window->redraw (true, titleEncoding->getLocation().x, 
     titleEncoding->getLocation().y, titleEncoding->getSize().width, 
     titleEncoding->getSize().height);
  SDimension td = title->getPreferredSize();
  SDimension ted = titleEncoding->getPreferredSize();
  unsigned int sx = 
     (td.width + ted.width > getSize().width) 
        ? 0 : (getSize().width - td.width - ted.width)/2;
  //titleEncoding->move (SLocation (sx,0));
  titleEncoding->move (SLocation (0,0));
  titleEncoding->resize (SDimension (ted.width, td.height));

  title->move (SLocation (sx+(int)ted.width,0));
  title->resize (SDimension (td));

  window->redraw (true, title->getLocation().x, 
     title->getLocation().y, title->getSize().width, title->getSize().height);
  window->redraw (true, titleEncoding->getLocation().x, 
     titleEncoding->getLocation().y, titleEncoding->getSize().width, 
     titleEncoding->getSize().height);

  /* we only need to do it once. */
  if (!xmanagerCludge)
  {
    return;
  }
  xmanagerCludge = false;

  /**
   * This is XManager bug wrokaround. 
   * We don't really need to resize these guys.
   */
  for (unsigned int i=0; i<(unsigned int) SS_MAX; i++)
  {
    SDimension wp;
    switch  (i)
    {
    case SS_PARAGRAPH_BREAK:
      wp = getMaxSize (buttons[i], paragraphBreakStrings, 
           paragraphBreakStrings[currentParagraphSeparator]);
      break;
    case SS_FONT:
      wp = getMaxSize (buttons[i], fonts, fonts[currentFont]);
      break;
    case SS_INPUT:
      wp = getMaxSize (buttons[i], displayInputs, displayInputs[currentInput]);
      break;
    default:
      wp = buttons[i]->getPreferredSize();
    }
    buttons[i]->resize(wp);
  }
}

void
SToolBar::setListener (SToolBarListener* l)
{
  listener = l;
}


void
SToolBar::redraw(SWindow* w, int x, int y,
     unsigned int width ,unsigned int height)
{
  SPanel::redraw(w, x, y, width, height);
}

void
SToolBar::buttonPressed (void* source, const SAccelerator* accel)
{
  for (unsigned int i=0; i<(unsigned int) SS_MAX; i++)
  {
    if (source == buttons[i])
    {
      if (i == SS_SET_OVERRIDE)
      {
        if (listener) listener->buttonPressed (this, i, accel!=0);
        /* it is listener->buttonPressed that can change it */
        break;
      }
      if (i == SS_SET_EMBEDDING)
      {
        if (listener) listener->buttonPressed (this, i, accel!=0);
        /* it is listener->buttonPressed that can change it */
        break;
      }
      if (i == SS_YIELD_EMBEDDING)
      {
        if (listener) listener->buttonPressed (this, i, accel!=0);
        /* it is listener->buttonPressed that can change it */
        break;
      }
      int indx = getFAccelerator (accel);
      switch (i)
      {
      case SS_DOCUMENT_EMBEDDING:
        indx = (((int)currentEmbedding)+1) % 3;
        setEmbedding ((SS_Embedding)indx, true);
        break;
      case SS_PARAGRAPH_BREAK:
        indx = (currentParagraphSeparator+1) % paragraphBreaks.size();
        setParagraphSeparator (indx, true);
        break;
      case SS_INPUT:
        if (accel==0)
        {
          if (listener) listener->buttonPressed (this, i, false);
          return;
        }
        if (indx < 0 && inputs.size() > 1)
        {
          indx = currentInput;
          do {
            indx = (indx+1) % inputs.size();
            if (inputs[(unsigned int)indx] != "None" &&
              inputs[(unsigned int)indx] != "none")
            {
              break;
            }
          } while (indx != (int)currentInput);
        }
        setInput (indx);
        break;
      case SS_MAGNIFY_PLUS:
        if (currentFontSize+1==fontsizes.size()) break;
        setFontSize ((int)currentFontSize+1);
        break;
      case SS_MAGNIFY_MINUS:
        if (currentFontSize ==0) break;
        setFontSize ((int)currentFontSize-1);
        break;
      case SS_FONT:
        if (indx < 0 && fonts.size() > 1)
        {
          indx = currentFont;
          do {
            indx = (indx+1) % fonts.size();
            if (fonts[(unsigned int)indx] != "None" &&
              fonts[(unsigned int)indx] != "none")
            {
              break;
            }
          } while (indx != (int)currentFont);
        }
        setFont (indx);
        break;
      default:
        if (listener) listener->buttonPressed (this, i, accel!=0);
      }
    }
  }
}
void
SToolBar::enterWindow (void* source)
{
  for (unsigned int i=0; i<(unsigned int) SS_MAX; i++)
  {
    if (source == buttons[i])
    {
      SString str;
      int max = -1;
      switch (i)
      {
      case SS_OPEN: str = translate ("__O__pen"); break;
      case SS_FIND: str = translate ("Find(__Q__)"); break;
      case SS_GOTO: str = translate ("__G__o To"); break;
      case SS_SAVE: 
       if (modified)
       {
         str = translate ("__S__ave (needed)");
       }
       else
       {
         str = translate ("__S__ave");
       }
       break;
      case SS_PRINT:
       if (printing)
       {
         str = translate ("__P__rint (pending job)"); break;
       }
       else
       {
         str = translate ("__P__rint"); break;
       }
      case SS_PRINT_PREVIEW:
       if (printing)
       {
          str = translate ("Print Previe__w__ (pending job)"); break;
       }
       else
       {
          str = translate ("Print Previe__w__"); break;
       }
      case SS_UNDO: str = translate ("__U__ndo"); break;
      case SS_REDO:  str = translate ("__R__edo"); break;
      case SS_DOCUMENT_EMBEDDING: str = translate ("Document __T__ext Embedding"); break;
      case SS_SET_OVERRIDE: str = translate ("__D__irection Override"); break;
      case SS_SET_EMBEDDING: str = translate ("__E__mbedding Override"); break;
      case SS_YIELD_EMBEDDING: str = translate ("__Y__ield Embedding"); break;
      case SS_MAGNIFY_MINUS: str = translate ("Smaller(__A__)"); break;
      case SS_MAGNIFY_PLUS: str = translate ("Bigger(__Z__)"); break;
      case SS_HIGHLIGHTING: str = translate ("__H__ighlighting"); 
        if (highlightName != "")
        {
          str.append (" ");
          str.append (highlightName);
        }
        break;
      case SS_FONT: str = translate ("Font");
        max = (int)fonts.size();
        break;
      case SS_INPUT: str = translate ("Input");
        max = (int)inputs.size();
        break;
      case SS_PARAGRAPH_BREAK: str = translate ("Line Break"); break;
      default:
         break;
      }
      if (max > 0)
      {
        char aa[64];
        if (max > 1)
        {
           sprintf (aa, "%s(__%sF1..F%d__)%s", SS_LB_LRE,
             (i==(unsigned int)SS_FONT) ? "shift-" : "",
             (max), SS_LB_PDF);
        }
        else
        {
           sprintf (aa, "%s(__%sF1__)%s", SS_LB_LRE, 
             (i==(unsigned int)SS_FONT) ? "shift-" : "", SS_LB_PDF);
        }
        str.append (SString(aa));
      }
      SLocation loc = buttons[i]->getLocation ();
      tooltip->setText (str);
      SDimension ld=tooltip->getPreferredSize();

      SLocation lmax((int) getSize().width - (int)ld.width, 2);
      if (lmax.x < loc.x) loc.x = lmax.x;
      loc.y = 0;
      tooltip->move (loc);
      tooltip->resize (ld);
      tooltip->setBackground (SColor("black"));
      tooltip->setLabelBackground (SColor("yellow").lighter().lighter());
      if (listener) listener->buttonLeave (this, i);
    }
  }
}
void
SToolBar::leaveWindow (void* source)
{
  for (unsigned int i=0; i<(unsigned int) SS_MAX; i++)
  {
    if (source == buttons[i])
    {
      tooltip->setText ("");
      tooltip->move (SLocation (0, - 2 *(int)getSize().height));
      if (listener) listener->buttonEnter (this, i);
    }
  }
}
/**
 * Assign the button all text in list and get the max size
 */
SDimension
SToolBar::getMaxSize (SButton* b, const SStringVector&l, const SString& orig)
{
  SDimension max;
  for (unsigned int i=0; i<l.size(); i++)
  {
    b->setText (l[i]);
    SDimension d = b->getPreferredSize();
    if (d.width > max.width) max.width = d.width;
    if (d.height > max.height) max.height = d.height;
  }
  b->setText (orig);
  return SDimension (max);
}
/**
 * Make an F-key accelerator 
 */
void
SToolBar::setFAccelerator (SButton* b, unsigned int se, bool ctrl)
{
  for (unsigned int i=0; i<se && i<12; i++)
  {
    SWindowListener::SKey key = SWindowListener::Key_Undefined;
    switch (i)
    {
    case 0: key = SWindowListener::Key_F1; break;
    case 1: key = SWindowListener::Key_F2; break;
    case 2: key = SWindowListener::Key_F3; break;
    case 3: key = SWindowListener::Key_F4; break;
    case 4: key = SWindowListener::Key_F5; break;
    case 5: key = SWindowListener::Key_F6; break;
    case 6: key = SWindowListener::Key_F7; break;
    case 7: key = SWindowListener::Key_F8; break;
    case 8: key = SWindowListener::Key_F9; break;
    case 9: key = SWindowListener::Key_F10; break;
    case 10: key = SWindowListener::Key_F11; break;
    case 11: key = SWindowListener::Key_F12; break;
    }
    if (key == SWindowListener::Key_Undefined) continue;
    b->addAccelerator (key, ctrl, false, false);
    if (ctrl)
    {
      b->addAccelerator (key, false, ctrl, false);
      b->addAccelerator (key, ctrl, ctrl, false);
      b->addAccelerator (key, false, false, ctrl);
      b->addAccelerator (key, ctrl, false, ctrl);
      b->addAccelerator (key, false, ctrl, ctrl);
      b->addAccelerator (key, ctrl, ctrl, ctrl);
    }
  }
}

/**
 * decode the F-Key
 */
int
SToolBar::getFAccelerator (const SAccelerator* accel)
{
  if (accel==0) return -1;
  int ret = -1;
  switch (accel->key)
  {
  case SWindowListener::Key_F1: ret = 0; break;
  case SWindowListener::Key_F2: ret = 1; break;
  case SWindowListener::Key_F3: ret = 2; break;
  case SWindowListener::Key_F4: ret = 3; break;
  case SWindowListener::Key_F5: ret = 4; break;
  case SWindowListener::Key_F6: ret = 5; break;
  case SWindowListener::Key_F7: ret = 6; break;
  case SWindowListener::Key_F8: ret = 7; break;
  case SWindowListener::Key_F9: ret = 8; break;
  case SWindowListener::Key_F10: ret = 9; break;
  case SWindowListener::Key_F11: ret = 10; break;
  case SWindowListener::Key_F12: ret = 11; break;
  default: 
    break;
  }
  return ret;
}

void
SToolBar::setFont (int index)
{
  if (index < 0) return;
  if (index >= (int)fonts.size()) return;
  if (index == (int) currentFont) return;
  if (fonts[(unsigned int)index] == "none" || fonts[(unsigned int)index] == "None") return;
  currentFont = index;
  setButton (SS_FONT, fonts[currentFont], true); 
}

void
SToolBar::setFontSize (int index)
{
  if (index < 0) return;
  if (index >= (int)fontsizes.size()) return;
  if (index == (int) currentFontSize) return;
  bool up = (index > (int)currentFontSize);
  currentFontSize = index;
  setButton (up ? SS_MAGNIFY_PLUS : SS_MAGNIFY_MINUS, fontsizes[currentFontSize], true); 
}

void
SToolBar::setInput (int index)
{
  if (index < 0) return;
  if (index >= (int)inputs.size()) return;
  if (index == (int) currentInput) return;
  if (inputs[(unsigned int)index] == "none" 
         || inputs[(unsigned int)index] == "None") return;
  currentInput = index;
  setButton (SS_INPUT, displayInputs[currentInput], true); 
}

void
SToolBar::setParagraphSeparator (int index, bool notify)
{
  if (index < 0) return;
  if (index >= (int) paragraphBreaks.size()) return;
  if (index == (int) currentParagraphSeparator) return;
  currentParagraphSeparator = (unsigned int) index;
  setButton (SS_PARAGRAPH_BREAK, paragraphBreakStrings[currentParagraphSeparator], notify); 
}

void
SToolBar::setEmbedding (SS_Embedding index, bool notify)
{
  if (index ==  currentEmbedding) return;
  currentEmbedding = index;
  setButton (SS_DOCUMENT_EMBEDDING, SString(), notify); 
}

void
SToolBar::setButton (SButtonIndex index, const SString& txt, bool notify)
{
  switch (index)
  {
  case SS_DOCUMENT_EMBEDDING:
  case SS_PARAGRAPH_BREAK:
  case SS_INPUT:
  case SS_MAGNIFY_PLUS:
  case SS_MAGNIFY_MINUS:
  case SS_FONT:
    break;
  default:
    return;
  }
  SButton* b = buttons[index];
  if (index == SS_PARAGRAPH_BREAK)
  {
    SIcon* icon = 0;
    switch (currentParagraphSeparator)
    {
    case SS_FORMAT_UNIX:
      icon = SIconFactory::getIcon("UNIX"); break;
    case SS_FORMAT_DOS:
      icon = SIconFactory::getIcon("DOS"); break;
    case SS_FORMAT_MAC:
      icon = SIconFactory::getIcon("MAC"); break;
    case SS_FORMAT_PS:
      icon = SIconFactory::getIcon("PS"); break;
    default:
      break;
    }
    b->setIcon (icon);
  }
  if (index == SS_DOCUMENT_EMBEDDING)
  {
    SIcon* icon = 0;
    switch (currentEmbedding)
    {
    case SS_EmbedNone:
      icon = SIconFactory::getIcon("EmbedNone"); break;
    case SS_EmbedLeft:
      icon = SIconFactory::getIcon("EmbedLeft"); break;
    case SS_EmbedRight:
      icon = SIconFactory::getIcon("EmbedRight"); break;
    default:
      break;
    }
    b->setIcon (icon);
  }
  if (index != SS_MAGNIFY_PLUS 
     && index != SS_MAGNIFY_MINUS && index != SS_DOCUMENT_EMBEDDING)
  {
    b->setText (txt);
  }
  if (notify && listener)
  {
    listener->buttonPressed (this, (unsigned int) index, true);
  }
}

void
SToolBar::setModified (bool flag)
{
  if (flag == modified) return;
  modified = flag;
  if (modified)
  {
    //buttons[SS_SAVE]->setButtonBackground (SColor("#DF0049"));
    buttons[SS_SAVE]->setIcon (SIconFactory::getIcon("Save"));
  }
  else
  {
    //buttons[SS_SAVE]->setButtonBackground (background);
    buttons[SS_SAVE]->setIcon (SIconFactory::getIcon("SaveNotNeeded"));
  }
}
void
SToolBar::setPrinting (bool flag)
{
  if (flag == printing) return;
  printing = flag;
  if (printing)
  {
    buttons[SS_PRINT]->setButtonBackground (SColor("#DF0049"));
    buttons[SS_PRINT_PREVIEW]->setButtonBackground (SColor("#DF0049"));
  }
  else
  {
    buttons[SS_PRINT]->setButtonBackground (background);
    buttons[SS_PRINT_PREVIEW]->setButtonBackground (background);
  }
}

/**
 * The direction has changed in editor - redo ours.
 */
void
SToolBar::directionChanged (bool lr)
{
  if (overrideLR == lr)
  {
    buttons[SS_SET_OVERRIDE]->setIcon (SIconFactory::getIcon(
      !overrideLR ? "LRO" : "RLO"));
  }
  if (embedLR == lr)
  {
   buttons[SS_SET_EMBEDDING]->setIcon (SIconFactory::getIcon(
      !embedLR ? "LRE" : "RLE"));
  }
  if (currentLR != lr)
  {
    buttons[SS_YIELD_EMBEDDING]->setIcon (SIconFactory::getIcon(
      !currentLR ? "LR" : "RL"));
  }

  overrideLR = !lr;
  embedLR = !lr;
  currentLR = lr;

}

void
SToolBar::syntaxChanged (SS_EventType _evnt)
{
  currentEvent = (int)_evnt;
  if (currentEvent != displayEvent) iconUpdater->start ();
}

SIconUpdater::SIconUpdater (SWindow* _w, SOpaqueLabel* _label, 
   int* _currentEvent, int* _displayEvent)
{
  label = _label;
  window = _w;
  currentEvent = _currentEvent;
  displayEvent = _displayEvent;
  eventTimer = 0;
}

SIconUpdater::~SIconUpdater ()
{
  if (eventTimer) delete eventTimer;
}

void
SIconUpdater::start ()
{
  if (eventTimer) return;
  eventTimer = STimer::newTimer(1000, this);
}

bool
SIconUpdater::timeout (const SEventSource* s)
{
  delete eventTimer;
  eventTimer = 0;
  if (*displayEvent == *currentEvent)
  {
    return false;
  }
  *displayEvent = *currentEvent;
  SSyntaxListener::SS_EventType _evnt 
       = (SSyntaxListener::SS_EventType) *displayEvent;
  switch (_evnt)
  {
  case SSyntaxListener::SD_PARSING_STARTED:
    label->setIcon (SIconFactory::getIcon("DocumentXX"));
    break;
  case SSyntaxListener::SD_PARSING_DONE:
    label->setIcon (SIconFactory::getIcon("Document"));
    break;
  default:
    label->setIcon (SIconFactory::getIcon("DocumentCX"));
    break;
  }
  window->redraw (true, label->getLocation().x, 
     label->getLocation().y, label->getSize().width, 
     label->getSize().height);

  return false;
}
