/**********************************************************************
This file is part of Crack dot Com's free source code release of Golgotha.
for information about compiling & licensing issues visit this URL
 If that doesn't help, contact Jonathan Clark at 
  golgotha_source@usa.net (Subject should have "GOLG" in it) 
***********************************************************************/

#include "gui/tab_bar.hh"
#include "memory/array.hh"
#include "window/style.hh"

struct tab
{
  i4_menu_item_class *tab_top;
  i4_window_class *tab_body;
  int desired_width;    
};

enum { LEFT_SPACING=5,
       RIGHT_SPACING=5,
       TAB_TOP_MARGIN=6,
       TAB_BOTTOM_MARGIN=4,
       TAB_LEFT_MARGIN=3,
       TAB_RIGHT_MARGIN=3 };
       
       

struct i4_tab_bar_data
{
  i4_array tabs;
  int current_tab;
  int top_height;
  i4_graphical_style_class *style;

  i4_tab_bar_data()
    : tabs(0,8)
  {
    top_height=0;
  }

};


i4_tab_bar::i4_tab_bar(int width, int height, i4_graphical_style_class *style)
  : i4_menu_class(i4_F)
{
  data=new i4_tab_bar_data();
  data->style=style;
  private_resize(width, height);
    
}

i4_tab_bar::~i4_tab_bar()
{
  delete data;  
 
}


void i4_tab_bar::private_resize(w16 new_width, w16 new_height)
{
  i4_parent_window_class::private_resize(new_width, new_height);
  if (!data->tabs.size())
    return ;
 
 
  int i, t_tabs=data->tabs.size();
  remove_child(data->tabs[data->current_tab].tab_body);

  for (i=0; itabs[i].tab_top);




  int available_size=width()-LEFT_SPACING-RIGHT_SPACING-t_tabs*(TAB_LEFT_MARGIN+TAB_RIGHT_MARGIN);

  int suggested_size=available_size / t_tabs;
  int leftover_size=0;
  
  for (i=0; itabs[i].desired_widthtabs[i].desired_width;

  leftover_size+=available_size-suggested_size*t_tabs;


  int client_w=width()-4;
  int client_h=height()-data->top_height-TAB_TOP_MARGIN-TAB_BOTTOM_MARGIN;
  
  int xpos=LEFT_SPACING + TAB_LEFT_MARGIN;
  int ypos=TAB_TOP_MARGIN-2;
  for (i=0; itabs[i].desired_width-suggested_size;
    if (additional_size_needed>0)
    {      
      if (additional_size_needed>leftover_size)
      {
        new_w=suggested_size+leftover_size;        
        leftover_size=0;
      }
      else
      {
        leftover_size-=additional_size_needed;
        new_w=data->tabs[i].desired_width;
      }
    }
    else new_w=data->tabs[i].desired_width;
      

    data->tabs[i].tab_top->resize(new_w, data->top_height);
    i4_parent_window_class::add_child(xpos, ypos, data->tabs[i].tab_top);

    data->tabs[i].tab_body->resize(client_w, client_h);
    if (i==data->current_tab)
      i4_parent_window_class::add_child(2, data->top_height+TAB_TOP_MARGIN, data->tabs[i].tab_body);

    xpos+=new_w+TAB_LEFT_MARGIN+TAB_RIGHT_MARGIN;
  }
}



void i4_tab_bar::add_tab(i4_menu_item_class *tab_top, i4_window_class *tab_body)
{
  i4_parent_window_class::add_child(0,0, tab_top);
  if (!data->tabs.size())
  {
    data->current_tab=0;   
    i4_parent_window_class::add_child(0,0, tab_body);
  }

  if (tab_top->height()>data->top_height)
    data->top_height=tab_top->height();


  tab t;
  t.tab_top=tab_top;
  t.tab_body=tab_body;
  t.desired_width=tab_top->width();  
  data->tabs.add(t);

  tab_top->set_menu_parent(this);

  resize(width(), height());
}



void i4_tab_bar::set_current_tab(int tab_number)
{
  if (!data->tabs.size() || tab_number==data->current_tab)
    return ;

  i4_window_class *client=data->tabs[data->current_tab].tab_body;
  int cx=client->x()-x(), cy=client->y()-y();


  remove_child(client);
  if (tab_number<0) tab_number=0;
  if (tab_number>=data->tabs.size())
    tab_number=data->tabs.size()-1;

  data->current_tab=tab_number;
  i4_parent_window_class::add_child(cx, cy, data->tabs[tab_number].tab_body);
}


void i4_tab_bar::note_reaction_sent(i4_menu_item_class *who,
                                    i4_event_reaction_class *ev,
                                    i4_menu_item_class::reaction_type type)
{
  if (type==i4_menu_item_class::PRESSED)
  {
    for (int i=0; itabs.size(); i++)
      if (who==data->tabs[i].tab_top)
        set_current_tab(i);
  }
}




void i4_tab_bar::parent_draw(i4_draw_context_class &context)
{ 
  data->style->deco_neutral_fill(local_image, 0,0, width()-1, height()-1, context);


  w32 black=0, 
    bright=data->style->color_hint->button.passive.bright,
    med=data->style->color_hint->button.passive.medium,
    dark=data->style->color_hint->button.passive.dark;
    
  i4_image_class *im=local_image;

  int dx=LEFT_SPACING, dy=0;
  int cur=data->current_tab;


  int client_y=TAB_TOP_MARGIN+data->top_height;
  int client_h=data->tabs[0].tab_body->height();

  im->bar(0, client_y-2, width()-1, client_y-2, bright, context);
  im->bar(1, client_y-1, width()-2, client_y-1, med, context);

  im->bar(0, client_y-2, 0, client_y+client_h+2, bright, context);
  im->bar(1, client_y-1, 1, client_y+client_h+1, med, context);

  im->bar(width()-2, client_y, width()-2, client_y+client_h+1, dark, context);
  im->bar(width()-1, client_y-1, width()-1, client_y+client_h+2, black, context);

  im->bar(2, client_y+client_h+1, width()-2, client_y+client_h+1, dark, context);
  im->bar(1, client_y+client_h+2, width()-1, client_y+client_h+2, black, context);

  

  for (int i=0; itabs.size(); i++)
  {
    int x1=dx, y1=dy+2, x2=dx+data->tabs[i].tab_top->width()+TAB_LEFT_MARGIN+TAB_RIGHT_MARGIN-1, 
      y2=dy+TAB_TOP_MARGIN+data->top_height-3;

    if (i==cur)
    {
      y1-=2;
      y2+=2;
      x1+=1;
      x2+=1;
    }

    if (i-1!=cur)
      im->bar(x1, y1+2, x1, y2, bright, context);    // left edge
    im->bar(x1+1, y1+1, x1+1, y1+1, bright, context);    // round off left edge to top


    im->bar(x1+2, y1, x2-(i+1==cur ? 1 : 2), y1, bright, context);  // top edge
     

    if (i+1!=cur)
    {
      im->bar(x2-1, y1, x2-1, y2, dark, context);
      im->bar(x2, y1+1, x2, y2, black, context);
    }

    if (i==cur)
      data->style->deco_neutral_fill(im, x1+1, y2-2, x2-2, y2, context);
          
    dx+=data->tabs[i].tab_top->width()+TAB_LEFT_MARGIN+TAB_RIGHT_MARGIN;
  }
}