/** 
 *  Yudit Unicode Editor Source File
 *
 *  GNU Copyright (C) 1997-2023  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/SHighlightD.h"
#include "swidget/SIcon.h"
#include "swidget/SIconFactory.h"
#include "stoolkit/SUtil.h"
#include "stoolkit/SEncoder.h"
#include "stoolkit/syntax/SSyntax.h"
#include "swindow/SAwt.h"


/**
 * Remark: 
 * Category  Highlight    
 * +-------+ +-------+ 
 * |       | |       | 
 * |       | |       | 
 * |       | |       | 
 * +-------+ +-------+ 
 * Folder       
 * OK           Cancel
 */
SHighlightD::SHighlightD (void)
{
  setFrameListener (this);
  isCancel = true;

  yesButton = new SButton (translate ("OK"), SIconFactory::getIcon("Yes"));
  yesButton->setAlignment (SD_Center);
  yesButton->setButtonListener (this);

  cancelButton = new SButton (translate ("Cancel"), SIconFactory::getIcon("Cancel"));
  cancelButton->setAlignment (SD_Center);
  cancelButton->setButtonListener (this);

  add (yesButton);
  add (cancelButton);

  categoryListBox = new SListBox(translate ("Category"));
  categoryListBox->setListListener (this);
  add (categoryListBox);

  highlightListBox = new SListBox(translate ("Highlighting"));
  highlightListBox->setListListener (this);
  add (highlightListBox);


  folderTitleLabel = new SLabel (translate ("Folder:"));
  add (folderTitleLabel);
  folderNameLabel = new SLabel ("FolderNameLabel");
  add (folderNameLabel);

  remarkTitleLabel  = new SLabel (translate ("Remark:"));
  add (remarkTitleLabel);
  remarkNameLabel = new SLabel ("");
  add (remarkNameLabel);
  recalc();
}

void
SHighlightD::setApplicationImage (const SImage& image)
{
  getComponentWindow()->setApplicationImage (image);
}

SHighlightD::~SHighlightD ()
{
}


/**
 * recalcualte the geometry
 * it is based upon 300x200 layout.
 * preferredSize will be calculated here.
 */
void
SHighlightD::recalc ()
{
  unsigned int bw = 1;
  if (yesButton->getPreferredSize().width > bw )
  {
     bw = yesButton->getPreferredSize().width;
  }
  if (cancelButton->getPreferredSize().width > bw )
  {
     bw = cancelButton->getPreferredSize().width;
  }
  unsigned int bh= cancelButton->getPreferredSize().height;


  int MGN = (int) (SAwt::getScale() * 5);
  int PW = (int) (SAwt::getScale() * 300);
  int PH = (int) (SAwt::getScale() * 200);

  yesButton->setLayout (
    SLayout (
      SLocation (MGN, PH-MGN-bh),
      SLocation ((int)bw + MGN , PH-MGN),
      SLocation (0, 100),
      SLocation (0, 100)
    )
  );
  cancelButton->setLayout (
    SLayout (
      SLocation (PW-MGN-(int)bw, PH-MGN-bh),
      SLocation (PW-MGN, PH-MGN),
      SLocation (100, 100),
      SLocation (100, 100)
    )
  );
  int currenty = PH-MGN-bh-MGN;

  SDimension fts = folderTitleLabel->getPreferredSize();
  folderTitleLabel->setLayout (
    SLayout (
      SLocation (MGN, currenty-(int)fts.height),
      SLocation ((int)fts.width+MGN, currenty),
      SLocation (0, 100),
      SLocation (0, 100)
    )
  );

  SDimension fns = folderNameLabel->getPreferredSize();
  folderNameLabel->setLayout (
    SLayout (
      SLocation ((int)fts.width+MGN+MGN, currenty-(int)fts.height),
      SLocation (PW-MGN, currenty),
      SLocation (0, 100),
      SLocation (100, 100)
    )
  );

  currenty = currenty-fts.height-5;

  SDimension rts = remarkTitleLabel->getPreferredSize();
  remarkTitleLabel->setLayout (
    SLayout (
      SLocation (MGN, MGN),
      SLocation ((int)rts.width+MGN, (int)rts.height+MGN),
      SLocation (0, 0),
      SLocation (0, 0)
    )
  );

  SDimension rtn = remarkNameLabel->getPreferredSize();
  remarkNameLabel->setLayout (
    SLayout (
      SLocation ((int)rts.width+MGN+MGN, MGN),
      SLocation (PW-MGN, (int)rts.height+MGN),
      SLocation (0, 0),
      SLocation (100, 0)
    )
  );

  int topY = rts.height+MGN+MGN;
  categoryListBox->setLayout (
    SLayout (
      SLocation (MGN, topY),
      SLocation (PW/2-MGN/2, currenty),
      SLocation (0, 0),
      SLocation (50, 100)
    )
  );
  highlightListBox->setLayout (
    SLayout (
      SLocation (PW/2+MGN/2, topY),
      SLocation (PW-MGN, currenty),
      SLocation (50, 0),
      SLocation (100, 100)
    )
  );

  unsigned int listW = categoryListBox->getPreferredSize().width;
  if (highlightListBox->getPreferredSize().width > listW)
  {
    listW = highlightListBox->getPreferredSize().width;
  }
  if (yesButton->getPreferredSize().width > listW)
  {
    listW = yesButton->getPreferredSize().width;
  }
  if (cancelButton->getPreferredSize().width > listW)
  {
    listW = cancelButton->getPreferredSize().width;
  }

  unsigned int h = MGN + yesButton->getPreferredSize().height
     + MGN + folderTitleLabel->getPreferredSize().height
     + MGN + 4 * folderTitleLabel->getPreferredSize().height
     + MGN + remarkTitleLabel->getPreferredSize().height + MGN;

  SDimension minimumSize = SDimension (4 * MGN + listW * 2, h);

  //preferredSize = SDimension (350, 250);
  preferredSize = SDimension (PW, PH);
  if (preferredSize.width < minimumSize.width) 
     preferredSize.width = minimumSize.width;
  if (preferredSize.height < minimumSize.height) 
     preferredSize.height = minimumSize.height;

  /* This was out layout... */
  forceLayout (SLayout (SDimension (PW,PH)));

  /* But this one is the one that works */
  setLayout (SLayout (preferredSize));


  setMinimumSize (minimumSize);

  resize (preferredSize);

}

SString
SHighlightD::getHighlightName ()
{
  if (currentCat == "simple") return currentHi;
  SString ret;
  ret.append (currentCat);
  ret.append (":");
  ret.append (currentHi);
  return SString(ret); 
}

bool
SHighlightD::getInput (const SString& titleString) 
{
  setTitle (titleString);
  center();
  isCancel = true;
  show();
  wait();
  hide();
  return !isCancel;
}

// Populate Category
void
SHighlightD::populate ()
{
  SStringVector l = SSyntax::getCategories ();
  l.insert (0, "simple");
  categoryListBox->setText (l);
}

// Populate Highlight in a category
void
SHighlightD::populate (const SString& cat)
{
  SStringVector l = (cat == "simple")
    ? SStringVector("none,simple,simple-dark", ",")
    : SSyntax::getAvaliableList (cat);
  highlightListBox->setText (l);
  if (l.size())
  {
    highlightListBox->selectItem (0);
    currentHi = l[0];
    highlightChanged ();
  }
  else
  {
    currentHi = "";
    highlightChanged ();
  }
}

/**
 * buttons call this
 */
void
SHighlightD::buttonPressedAccel (void* source, const SAccelerator* acc)
{
  if (source == cancelButton)
  {
    isCancel = true;
    hide();
    return;
  }
  if (source == yesButton)
  {
    isCancel = false;
    hide();
    return;
  }
}

/**
 * STextListListener
 */
void
SHighlightD::itemSelected (void* source, const SAccelerator* acc)
{
  if (source == categoryListBox->textList)
  {
     SString s = categoryListBox->textList->getLastSelectedText();
     currentCat = s;
     populate (s);
     highlightChanged ();
     return;
  }
  if (source == highlightListBox->textList)
  {
     SString s = highlightListBox->textList->getLastSelectedText();
     currentHi = s;
     highlightChanged ();
     return;
  }
}

bool
SHighlightD::close (SPanel* comp)
{
  isCancel =true;
  hide();
  return false;
}

/**
 * set the filename - cut off the dirpart
 */
void
SHighlightD::setHighlightName (const SString& _hm)
{
  SStringVector v (_hm, ":", true);
  SString cat = "simple";
  SString h = "simple";
  if (v.size() == 0) // never
  {
    h = "none";
  }
  else if (v.size() == 1)
  {
    h = v[0];
  }
  else
  {
    cat = v[0];
    h = v[1];
  }
  if (h=="") h = "none";
  currentCat = cat;
  currentHi = h;
  populate ();
  populate (cat);
  categoryListBox->selectText (cat);
  highlightListBox->selectText (h);
  highlightChanged ();
}

void
SHighlightD::highlightChanged ()
{
  SString s = currentCat;
  s.append (":");
  s.append (currentHi);
  SString dir = SSyntax::getFolderFor (s);
  folderNameLabel->setText (dir);
  SString mf = SSyntax::getMissingFile (s);
  if (mf.size())
  {
    SString s = translate ("Can not read: ");
    s.append (mf);
    remarkNameLabel->setText (s);
  }
  else
  {
    remarkNameLabel->setText ("");
  }
}

void
SHighlightD::setTitleForeground (const SColor& fg)
{
  yesButton->setForeground (fg, fg);
  cancelButton->setForeground (fg, fg);
  folderTitleLabel->setForeground (fg, fg);
  remarkTitleLabel->setForeground (fg, fg);
  categoryListBox->setLabelForeground (fg);
  highlightListBox->setLabelForeground (fg);
}

void 
SHighlightD::setLabelForeground (const SColor& fg)
{
  folderNameLabel->setForeground (fg);
  remarkNameLabel->setForeground (fg);
}

void
SHighlightD::setBackground (const SColor& bg)
{
  SFrame::setBackground (bg);
}

void
SHighlightD::setForeground (const SColor& lrfg, const SColor& rlfg)
{
  SFrame::setForeground (lrfg, rlfg);
  setLabelForeground (lrfg);
  setTitleForeground (lrfg);
}

void
SHighlightD::setSliderBackground (const SColor& bg)
{
  categoryListBox->setSliderBackground (bg);
  highlightListBox->setSliderBackground (bg);
}

void
SHighlightD::setFont (const SString& font, double fontSize)
{
  folderNameLabel->setFont (font, fontSize);
  folderTitleLabel->setFont (font, fontSize);
  yesButton->setFont (font, fontSize);
  cancelButton->setFont (font, fontSize);
  remarkTitleLabel->setFont (font, fontSize);
  remarkNameLabel->setFont (font, fontSize);
  categoryListBox->setFont (font, fontSize);
  highlightListBox->setFont (font, fontSize);
  recalc();
}

void
SHighlightD::setFontSize (double fontSize)
{
  folderNameLabel->setFontSize (fontSize);
  folderTitleLabel->setFontSize (fontSize);
  yesButton->setFontSize (fontSize);
  cancelButton->setFontSize (fontSize);
  remarkTitleLabel->setFontSize (fontSize);
  remarkNameLabel->setFontSize (fontSize);
  categoryListBox->setFontSize (fontSize);
  highlightListBox->setFontSize (fontSize);
  recalc();
}
