/* This file is part of cardwords
   (c) 1999 Tobias Peters
   see file COPYING for the copyright terms.
   
   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.

   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

// cardwords_gtk_common_card_cell_styles.cc

#include "cardwords_gtk_common_card_cell_styles.hh"
#include "cardwords_gettext.hh"

// The styles used for the background of the cells:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::attribute_bg_style[CAT_LAST + 1] = {
  0,0,0,0
};

// The styles used for the color of the frame
Gtk::Style * CardWords_Gtk_Common_Card_Cell_Styles::frame_normal_style = 0;
Gtk::Style * CardWords_Gtk_Common_Card_Cell_Styles::frame_active_style = 0;
//           used when the cell is selected to hold a card in the next move.

// The style used for the bg of the cards
Gtk::Style * CardWords_Gtk_Common_Card_Cell_Styles::card_bg_style = 0;

// The style used for the bg of cards that are not layed yet:
Gtk::Style * CardWords_Gtk_Common_Card_Cell_Styles::card_pre_bg_style = 0;

// The style used for the bg of cards that have most recently been layed:
Gtk::Style * CardWords_Gtk_Common_Card_Cell_Styles::card_recent_bg_style = 0;

CardWords_Gtk_Common_Card_Cell_Styles::
CardWords_Gtk_Common_Card_Cell_Styles (size_t cell_width,
                                       size_t cell_height)
{
  if (frame_normal_style == 0) {
    assert (frame_active_style    == 0);
    assert (card_bg_style         == 0);
    assert (card_pre_bg_style     == 0);
    assert (card_recent_bg_style  == 0);

    init_static_styles();
  }
  
  assert (frame_normal_style    != 0);
  assert (frame_active_style    != 0);
  assert (card_bg_style         != 0);
  assert (card_pre_bg_style     != 0);
  assert (card_recent_bg_style  != 0);

  values_font_style             =
    card_wildcard_meaning_style =
    card_face_value_style       =
    card_points_narrow_style    =
    card_points_wide_style      = 0;
  
  this->cell_width = this->cell_height = 0;

  frame_thickness       = 
    value_width         =
    word_factor_height   =
    letter_factor_height =
    card_width          =
    card_height         =
    face_value_height   =
    face_value_width    =
    points_narrow_height=
    points_wide_height  =
    points_narrow_width =
    points_wide_width   = 0;

  change_sizes (cell_width, cell_height);
}

CardWords_Gtk_Common_Card_Cell_Styles::
~CardWords_Gtk_Common_Card_Cell_Styles()
{
  delete values_font_style;
  delete card_wildcard_meaning_style;
  delete card_face_value_style;
  delete card_points_narrow_style;
  delete card_points_wide_style;
}

size_t
CardWords_Gtk_Common_Card_Cell_Styles::get_cell_width(void) const
{
  return cell_width;
}

size_t
CardWords_Gtk_Common_Card_Cell_Styles::get_cell_height(void) const
{
  return cell_height;
}

size_t
CardWords_Gtk_Common_Card_Cell_Styles::get_frame_thickness(void) const
{
  return frame_thickness;
}


void
CardWords_Gtk_Common_Card_Cell_Styles::change_sizes(size_t cell_width,
                                      size_t cell_height)
{
  size_t index;
  GtkStateType gtk_state;
  
  this->cell_width  = cell_width;
  this->cell_height = cell_height;

  frame_thickness = 1
    + ((cell_width < cell_height) ? cell_width : cell_height) / 29;
  
  value_width = cell_width - 2 * frame_thickness;

  word_factor_height   = (cell_height - 2 * frame_thickness) / 2;
  letter_factor_height = cell_height - 2 * frame_thickness - word_factor_height;
  
  card_width  = cell_width  - 2 * frame_thickness;
  card_height = cell_height - 2 * frame_thickness;

  face_value_height = card_height * 15 / 16;
  face_value_width  = card_width  * 8  / 16;
  
  points_narrow_height= card_height * 7 / 16;
  points_narrow_width = card_width  * 3 / 16;
  points_wide_height  = card_height * 8 / 16;
  points_wide_width   = card_width  * 4 / 16;


  // ****************   values_font_style    ********************
  if (values_font_style == 0) {
    values_font_style = Gtk::Style::create();
  }
  
  //  gdk_font_unref(values_font_style->get_font());

  {
    ostrstream fontname;
    fontname << "-*-lucidatypewriter-bold-r-normal-sans-"
             << word_factor_height
             << "-*-*-*-m-"
             << value_width / 3
             << "0-iso8859-1"
             << ends;
    fontname.freeze(true);
    
    (values_font_style->gtkobj())->font = gdk_font_load(fontname.str());
    if (values_font_style->gtkobj()->font == 0) {
      cerr << gettext("ERROR: font `")
           << fontname.str()
           << gettext("' for ")
           << "values_font_style->gtkobj()->font"
           << gettext(" not found. Error is currently unrecoverable.")
           << gettext(" It's a FIXME!")
           << endl;
      exit(1);
    }
    gdk_font_ref((values_font_style->gtkobj())->font);

    fontname.freeze(false);
  }



  // ****************   card_wildcard_meaning_style    *****************
  if (card_wildcard_meaning_style == 0) {
    card_wildcard_meaning_style = Gtk::Style::create();
  }
  
  //  gdk_font_unref(card_wildcard_meaning_style->get_font());

  GdkColor card_wildcard_meaning_fg = {0, 24000,24000,100};
  GdkColor card_wildcard_meaning_text = {0, 12000,12000,500};
  
  for (gtk_state = GTK_STATE_NORMAL;
       gtk_state <= GTK_STATE_INSENSITIVE;
       gtk_state = GtkStateType(gtk_state + 1)) {
    card_wildcard_meaning_style->set_fg(gtk_state, card_wildcard_meaning_fg);
    card_wildcard_meaning_style->set_text(gtk_state, card_wildcard_meaning_text);
  }
  {
    ostrstream fontname;
    fontname << "-*-lucidatypewriter-bold-r-normal-sans-"
             << face_value_height
             << "-*-*-*-m-"
             << face_value_width
             << "0-iso8859-1"
             << ends;
    fontname.freeze(true);
    
    (card_wildcard_meaning_style->gtkobj())->font =
      gdk_font_load(fontname.str());
    if (card_wildcard_meaning_style->gtkobj()->font == 0) {
      cerr << gettext("ERROR: font `")
           << fontname.str()
           << gettext("' for ")
           << "card_wildcard_meaning_style->gtkobj()->font"
           << gettext(" not found. Error is currently unrecoverable.")
           << gettext(" It's a FIXME!")
           << endl;
      exit(1);
    }

    gdk_font_ref((card_wildcard_meaning_style->gtkobj())->font);

    fontname.freeze(false);
  }
  
  // ****************     card_face_value_style    *****************
  if (card_face_value_style == 0) {
    card_face_value_style = Gtk::Style::create();
  }
  //  gdk_font_unref(  card_face_value_style->get_font());

  GdkColor card_face_value_fg = {0,0,0,0};
  GdkColor & card_face_value_text = card_face_value_fg;
  
  for (gtk_state = GTK_STATE_NORMAL;
       gtk_state <= GTK_STATE_INSENSITIVE;
       gtk_state = GtkStateType(gtk_state + 1)) {
      card_face_value_style->set_fg(gtk_state, card_face_value_fg);
      card_face_value_style->set_text(gtk_state, card_face_value_text);
  }
  (card_face_value_style->gtkobj())->font =
    (card_wildcard_meaning_style->gtkobj())->font;

  gdk_font_ref((card_face_value_style->gtkobj())->font);

  

  // ****************   card_points_narrow_style    *****************
  if (card_points_narrow_style == 0) {
    card_points_narrow_style = Gtk::Style::create();
  }
  //  gdk_font_unref(card_points_narrow_style->get_font());

  GdkColor card_points_narrow_fg = {0,0,0,0};
  GdkColor & card_points_narrow_text = card_face_value_fg;

  for (gtk_state = GTK_STATE_NORMAL;
       gtk_state <= GTK_STATE_INSENSITIVE;
       gtk_state = GtkStateType(gtk_state + 1)) {
    card_points_narrow_style->set_fg(gtk_state, card_points_narrow_fg);
    card_points_narrow_style->set_text(gtk_state, card_points_narrow_text);
  }
  {
    ostrstream fontname;
    fontname << "-*-lucidatypewriter-medium-r-normal-sans-"
             << points_narrow_height
             << "-*-*-*-m-"
             << points_narrow_width
             << "0-iso8859-1"
             << ends;
    fontname.freeze(true);
    
    (card_points_narrow_style->gtkobj())->font =
      gdk_font_load(fontname.str());
    if (card_points_narrow_style->gtkobj()->font == 0) {
      cerr << gettext("ERROR: font `")
           << fontname.str()
           << gettext("' for ")
           << "card_points_narrow_style->gtkobj()->font"
           << gettext(" not found. Error is currently unrecoverable.")
           << gettext(" It's a FIXME!")
           << endl;
      exit(1);
    }
    gdk_font_ref((card_points_narrow_style->gtkobj())->font);

    fontname.freeze(false);
  }
  
  
  // ****************   card_wildcard_meaning_style    *****************
  if (card_points_wide_style == 0) {
    card_points_wide_style = Gtk::Style::create();
  }
  
  //  gdk_font_unref(card_points_wide_style->get_font());

  GdkColor black = {0,0,0,0};
  for (index = 0; index < 5; ++index) {
    gtk_state = GtkStateType(index);
    card_points_wide_style->set_fg(gtk_state, black);
    card_points_wide_style->set_text(gtk_state, black);
  }
  {
    ostrstream fontname;
    fontname << "-*-lucidatypewriter-medium-r-normal-sans-"
             << points_wide_height
             << "-*-*-*-m-"
             << points_wide_width
             << "0-iso8859-1"
             << ends;
    fontname.freeze(true);
    
    (card_points_wide_style->gtkobj())->font =
      gdk_font_load(fontname.str());
    if (card_points_wide_style->gtkobj()->font == 0) {
      cerr << gettext("ERROR: font `")
           << fontname.str()
           << gettext("' for ")
           << "card_points_wide_style->gtkobj()->font"
           << gettext(" not found. Error is currently unrecoverable.")
           << gettext(" It's a FIXME!")
           << endl;
      exit(1);
    }
    gdk_font_ref((card_points_wide_style->gtkobj())->font);

    fontname.freeze(false);
  }
}


// The style used for the Labels that inform about the word and letter
// factors. These are only visible in an empty cell.
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_values_font_style(void) const
{
  return values_font_style;
}
  
// The styles used for the background of the cells:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::
get_attribute_bg_style(CardWords_Gtk_CellAttributeType type)
{
  assert (type == CAT_DEFAULT
          || type == CAT_WORD_FACTOR
          || type == CAT_LETTER_FACTOR
          || type == CAT_CELL_POINTS
          || type == CAT_BLOCKED);
  return attribute_bg_style[type];
}

// The styles used for the color of the frame
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_frame_normal_style(void)
{
  return frame_normal_style;
}

Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_frame_active_style(void)
  // used when the cell is selected to hold a card in the next move.
{
  return frame_active_style;
}

// The style used for the bg of the cards
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_card_bg_style(void)
{
  return card_bg_style;
}

// The style used for the bg of cards that are not layed yet:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_card_pre_bg_style(void)
{
  return card_pre_bg_style;
} 

// The style used for the bg of cards that have most recently been layed:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_card_recent_bg_style(void)
{
  return card_recent_bg_style;
}

// The style used for the meaning of a wildcard on the card:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::
get_card_wildcard_meaning_style(void) const
{
  return card_wildcard_meaning_style;
}

// The style used for the face value of a card:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_card_face_value_style(void) const
{
  return card_face_value_style;
}

// The style used for the points label on the card: 2 digits:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::
get_card_points_narrow_style(void) const
{
  return card_points_narrow_style;
}

// The style used for the points label on the card: 1 digit:
Gtk::Style *
CardWords_Gtk_Common_Card_Cell_Styles::get_card_points_wide_style(void) const
{
  return card_points_wide_style;
}

void
CardWords_Gtk_Common_Card_Cell_Styles::init_static_styles(void)
{
  assert (frame_normal_style    == 0);
  assert (frame_active_style    == 0);
  assert (card_bg_style         == 0);
  assert (card_pre_bg_style     == 0);
  assert (card_recent_bg_style  == 0);

  frame_normal_style    = Gtk::Style::create();
  frame_active_style    = Gtk::Style::create();
  card_bg_style         = Gtk::Style::create();
  card_pre_bg_style     = Gtk::Style::create();
  card_recent_bg_style  = Gtk::Style::create();

  size_t index;
  enum GtkStateType gtk_state;
  
  for (index = 0; index <= CAT_LAST; ++index) {
    attribute_bg_style[index] = Gtk::Style::create();
  }

  GdkColor word_factor_bg   = {0,0xcb00,0x6e00,0xe500};
  GdkColor letter_factor_bg = {0,0xea00,0x5800,0x3300};
  GdkColor default_bg       = {0,2000,35000,5000};
  GdkColor blocked_bg       = {0,0x200,0x200,0x200};
  GdkColor cell_points_bg   = {0,11000,65000,11000};
  GdkColor frame_normal_bg  = {0,0,0,0};
  GdkColor frame_active_bg  = {0,43000,43000,43000};
  GdkColor card_bg          = {0,0xE000,0xE000,0xE000};
  GdkColor card_pre_bg      = {0,0xD800,0xD800,0xFF00};
  GdkColor card_recent_bg   = {0,65530,0xA800,0xA800};
  GdkColor card_recent_fg   = {0,12000,12000,500};
  for (index = 0; index < 5; ++index) {
    gtk_state = GtkStateType(index);
    attribute_bg_style[CAT_WORD_FACTOR]->set_bg(gtk_state, word_factor_bg);

    attribute_bg_style[CAT_LETTER_FACTOR]->set_bg(gtk_state,
                                                  letter_factor_bg);

    attribute_bg_style[CAT_DEFAULT]->set_bg(gtk_state, default_bg);

    attribute_bg_style[CAT_BLOCKED]->set_bg(gtk_state, blocked_bg);

    attribute_bg_style[CAT_CELL_POINTS]->set_bg(gtk_state, cell_points_bg);

    frame_normal_style->set_bg(gtk_state, frame_normal_bg);

    frame_active_style->set_bg(gtk_state, frame_active_bg);

    card_bg_style->set_bg(gtk_state, card_bg);

    card_pre_bg_style->set_bg(gtk_state, card_pre_bg);

    card_recent_bg_style->set_bg(gtk_state, card_recent_bg);
    card_recent_bg_style->set_fg(gtk_state, card_recent_fg);
    card_recent_bg_style->set_text(gtk_state, card_recent_fg);
  }
}
