/* Tk panel stuff.
   Copyright (C) 1995 Miguel de Icaza
   
   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., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <config.h>
#include "fs.h"
#include "dir.h"
#include "tkmain.h"
#include "panel.h"
#include "command.h"
#include "panel.h"		/* current_panel */
#include "command.h"		/* cmdline */
#include "main.h"
#include "mouse.h"
#include "layout.h"		/* get_panel_widget */

void do_enter (WPanel *panel);

static char *attrib;

void set_attr (int h, int m)
{
}

void repaint_file (WPanel *panel, int file_index, int move)
{
}

void show_dir (WPanel *panel)
{
    char *tkw = wtk_win (panel->widget);
    
    tk_evalf ("%s.cwd configure -text {%s}", tkw, panel->cwd);
}

void x_fill_panel (WPanel *panel)
{
    const int top = panel->count;
    char  *panel_name, *tag;
    char  buffer [255];
    int i;
    int selected;
    
    if (!panel->widget.wcontainer)
	return;

    selected = panel->selected;
    
    panel_name = copy_strings (wtk_win (panel->widget), ".m.panel", 0);

    tk_evalf ("%s delete 0.0 end", panel_name);
    for (i = 0; i < top; i++){
	int marked = panel->dir.list [i].f.marked;
	
	/* FIXME: What is that 39 doing there? */
	format_file (buffer, panel, i, 39);

	if (i)
	    tk_evalf ("%s insert end \\n", panel_name);

	
	/* Set the mark tag name */
	tag = marked ? "ma" : "re";
	
	tk_evalf ("%s insert end {%s} %s", panel_name, buffer, tag);
    }
    if (panel->active)
	x_select_item (panel);
#if 0
    /* The first time, the panel does not yet have a command */
    if (panel->widget.wdata)
	x_select_item (panel);
    free (panel_name);
#endif
}

void x_panel_set_size (int index)
{
    Widget *w;
    char *pn;
    static old_width, old_height;
    int width, height;
    
    w = (Widget *) get_panel_widget (index);
    
    tk_evalf ("panel_width");
    width = atoi (interp->result);
    
    tk_evalf ("panel_height");
    height = atoi (interp->result);

    if (w && w->cols && w->lines)
	if ((width == old_width) && (height == old_height))
	    return;

    if ((width < 10) || (height < 3))
	return;
    
    old_width = width;
    old_height = height ;

    w = get_panel_widget (index);
    w->cols = width;
    w->lines = height;

    panel_update_format ((WPanel *) w);
    x_fill_panel ((WPanel *) w);
}

x_change_size (char *panel)
{
    if (strncmp (panel, ".left", 5) == 0)
	x_panel_set_size (0);
    else
	x_panel_set_size (1);
}

static char compute_font_size (char *font, char *win, char *dest)
{
    Tk_Uid    font_uid;
    Tk_Window window_id;
    XFontStruct *f;
    int width, height;
    
    font_uid = Tk_GetUid (font);
    window_id = Tk_NameToWindow (interp, win, Tk_MainWindow (interp));
    if (window_id == NULL){
	fprintf (stderr, "Error: %s\n\r", interp->result);
	exit (1);
    }
    f = Tk_GetFontStruct (interp, window_id, font_uid);

    if (f == NULL){
	fprintf (stderr, "This should not happend: %s\n", interp->result);
	exit (1);
    }

    width = f->max_bounds.width;
    height = f->ascent + f->descent;

    /* Ok, we will use this dummy until monday, the correct thing
     * to do is extract the Tk font information from Tk's hash
     * table (tkFont.c).
     *
     * TkFont->widths ['0'] holds the width
     */
    sprintf (dest, "%d %d", height, width);
    Tk_FreeFontStruct (f);
}

int tk_panel_callback (ClientData cd, Tcl_Interp *interp, int ac, char *av[])
{
    Gpm_Event e;
    WPanel *panel = (WPanel *) cd;
    char b [20];
    char *p;
    int  mouse_etype = 0;
    
    p = av [1];
    
    if (STREQ (p, "mdown"))
	mouse_etype = GPM_DOWN;
    else if (STREQ (p, "mup"))
	mouse_etype = GPM_UP;
    else if (STREQ (p, "double"))
	mouse_etype = GPM_DOUBLE|GPM_UP;
    else if (STREQ (p,  "motion"))
	mouse_etype = GPM_MOVE|GPM_DRAG;
    else if (STREQ (p, "resize")){
	x_change_size (av [2]);
	return TCL_OK;
    } else if (STREQ (p, "fontdim")){
	compute_font_size (av [2], av [3], interp->result);
	return TCL_OK;
    }

    if (STREQ (p, "top")){
	int old_sel = panel->selected;
	int new = old_sel;
	
	panel->top_file = atoi (av [2]) - 1;
	if (old_sel < panel->top_file)
	    new = panel->top_file;
	if (old_sel > (panel->top_file + ITEMS (panel)))
	    new = panel->top_file + ITEMS (panel) - 1;
	
	if (new != old_sel){
	    unselect_item (panel);
	    panel->selected = new;
	    select_item (panel);
	}
	return TCL_OK;
    }
    
    if (mouse_etype){
	for (p = av [3]; *p && *p != '.'; p++)
	    ;
	*p++ = 0;
	e.buttons = (1 << (atoi (av [2]) - 1));
    	e.y = atoi (av [3]) + 2 - panel->top_file;
	e.x = atoi (p);
	e.type = mouse_etype;
	panel_event (&e, panel);
    } else {
	/* We are currently dealing with those */
	fprintf (stderr, "Unknown command: %s\n", p);
	return TCL_ERROR;
    }
    return TCL_OK;
}

int x_create_panel (Dlg_head *h, widget_data parent, WPanel *panel)
{
    char *cmd;
    char *container = (char *) panel->widget.wcontainer;
    
    cmd = tk_new_command  (container, panel, tk_panel_callback, 'p');
    tk_evalf ("panel_setup %s", wtk_win (panel->widget));
    tk_evalf ("panel_bind %s %s", wtk_win (panel->widget), cmd);
    x_fill_panel (panel);
}

/* Called when f.marked has changed on a file */
void x_panel_select_item (WPanel *panel, int index, int value)
{
    char *s;

    s = value ? "add" : "remove";
    tk_evalf ("%s.m.panel tag %s ma %d.0 {%d.0 lineend}", 
        wtk_win (panel->widget), s, index+1, index+1);
}

void x_unselect_item (WPanel *panel)
{
    const int selected = panel->selected + 1;
    
    tk_evalf ("%s.m.panel tag remove se %d.0 {%d.0 lineend}",
        wtk_win (panel->widget), selected, selected);
}

void x_select_item (WPanel *panel)
{
    const int selected = panel->selected + 1;
    char *cmd = wtcl_cmd (panel->widget);

    if (!(cmd && *cmd))
	return;
    
    tk_evalf ("panel_select %s %d %s", wtk_win (panel->widget),
        selected, cmd);
}

void x_adjust_top_file (WPanel *panel)
{
    tk_evalf ("%s.m.panel yview %d.0", wtk_win (panel->widget),
         panel->top_file+1);
}
