/**
 * Line editor code
 * (C) Nettle developers 2000-2001
 *
 * $Id: lineedit,v 1.32 2003/10/26 23:08:53 ijeffray Exp $
 */

#include "generic.h"
#include "globals.h"

#include "lineedit.h"
#include "misc.h"
#include "wimp.h"
#include "wimputil.h"
#include "zapredraw.h"

static char line_editor_buffer_indirected[]="Pptr_write,2,4;KN";
static char line_editor_icon_text[]="";
static char line_editor_icon_sprite[]="Soptoff,opton";

static void resize_line_editor_icons(struct session_struct *session, int width)
{
  struct wimp_geticonstate_block iconstate;
  struct wimp_getcaretposition_block caret;
  bool has_checkbox = BOOL(session->line_editor_type==LINEEDIT_CHECKBOX_OFF || session->line_editor_type==LINEEDIT_CHECKBOX_ON);
  int checkbox_chop = has_checkbox ? 56 : 0;

  if (session->line_editor_type==LINEEDIT_NONE)
    return;

  iconstate.window_handle=session->pane_handle;
  iconstate.icon_handle=0;
  _swi(Wimp_GetIconState, _IN(1), &iconstate);

  if (width==(iconstate.max.x-4) + checkbox_chop )
    return;

  _swi(Wimp_GetCaretPosition, _IN(1), &caret);
  _swix( Wimp_ResizeIcon, _INR(0,5), session->pane_handle, 0, -4, -52, (width+4)-checkbox_chop, 4 );

  if (has_checkbox)
    _swix( Wimp_ResizeIcon, _INR(0,5), session->pane_handle, 1, width-48, -48, width, 0 );

  force_redraw(session->pane_handle, 0, -48, 1<<24, 0);

  if (caret.window_handle==session->pane_handle)
  {
    set_caret_position(caret.window_handle, 0, -1, caret.index);
  }

}


void open_pane_window(struct session_struct *session, struct wimp_openwindow_block *main_block)
{
  struct wimp_getwindowoutline_block gwo_block;
  struct wimp_openwindow_block window;
  struct wimp_getwindowstate_block gws_block;
  int width,height=0;

  width=main_block->max.x-main_block->min.x;

  if (width>session->terminal_size.x*redraw.r_charw << eig.x)
    width=session->terminal_size.x*redraw.r_charw << eig.x;

  gws_block.window_handle=session->window_handle;
  _swi(Wimp_GetWindowState, _IN(1), &gws_block);
  if (gws_block.window_flags & (1<<30))
    height=toolheight;

  gwo_block.window_handle=session->window_handle;
  _swi(Wimp_GetWindowOutline, _IN(1), &gwo_block);

  window.window_handle=session->pane_handle;
  window.min.x=main_block->min.x;
  window.min.y=(main_block->min.y)-height-48;
  window.max.x=window.min.x+width;

  window.max.y=(main_block->min.y)-height;
  window.scroll.x=0;
  window.scroll.y=0;
  window.handle_behind=main_block->handle_behind;

  resize_line_editor_icons(session, width);

  _swi(Wimp_OpenWindow, _IN(1), &window);
}


bool line_editor_active(struct session_struct *session)
{
  switch (session->line_editor_type)
  {
    case LINEEDIT_CHECKBOX_OFF:
    case LINEEDIT_CHECKBOX_ON:
      {
        struct wimp_geticonstate_block block;

        block.window_handle=session->pane_handle;
        block.icon_handle  =0;

        _swi(Wimp_GetIconState, _IN(1), &block);

        if ( (block.icon_flags & WIMP_ICON_DELETED_BIT) == 0)
          return true;

      }
      break;
    case LINEEDIT_ANTTERM:
      return true; /* antterm style is always on */
      break;
  }

  return false;
}

void lineedit_allocate_space(struct session_struct *session, bool dont_discard)
{
  int loop,width;
  struct wimp_createwindow_block window;
  struct wimp_createicon_block icon;
  bool has_checkbox = BOOL(session->line_editor_type==LINEEDIT_CHECKBOX_OFF || session->line_editor_type==LINEEDIT_CHECKBOX_ON);

  /* Note - this *must* be called if the lineeditor is turned on at any point */
  if (!dont_discard || session->line_editor_history == NULL)
  {
    session->line_editor_history=malloc(line_editor_size*MAX_LINEEDITOR_LENGTH*sizeof(char));
    assert(session->line_editor_history != NULL);
    session->line_editor_position=0;
    session->line_editor_total=1;

    for (loop=0; loop<line_editor_size; loop++)
    {
      strcpy(session->line_editor_history+(loop*MAX_LINEEDITOR_LENGTH),"");
    }

    /* When we create the line editor buffer we must always clear the input
     * buffer.
     */
    strcpy(session->line_editor_buffer,"");
  }

  /* Create new pane window */
  window.min.x=102;
  window.min.y=1088-(session->terminal_size.y*redraw.r_charh << eig.y)-40;
  window.max.x=102+(session->terminal_size.x*redraw.r_charw << eig.x);
  window.max.y=1088-(session->terminal_size.y*redraw.r_charh << eig.y);

  window.scroll.x=0;
  window.scroll.y=0;

  window.handle_behind=-1;
  window.window_flags =0x80080162;

  window.title_fg     =7;
  window.title_bg     =2;
  window.work_fg      =7;
  window.work_bg      =1;

  window.scroll_outer_colour=3;
  window.scroll_inner_colour=1;
  window.title_focus_colour =12;
  window.flags              =0;

  window.work_min.x=0;
  window.work_min.y=-48;
  window.work_max.x=session->terminal_size.x*redraw.r_charw << eig.x;
  window.work_max.y=0;

  window.icon_flags    =0x00000000;
  window.workarea_flags=0<<12;

  window.sprite_area=(struct os_spriteop_area *) 1;
  window.min_width  =4;
  window.min_height =4;

  window.title.it.text      =0;
  window.title.it.validation=0;
  window.title.it.text_len  =0;

  window.number_of_icons    =0;

  session->pane_handle=_swi(Wimp_CreateWindow, _IN(1)|_RETURN(0), &window);

  width = window.work_max.x - window.work_min.x;

  icon.window_handle=session->pane_handle;
  icon.min.x =-4;
  icon.min.y =-52;
  icon.max.x =width+4;
  icon.max.y =4;

  if (has_checkbox)
    icon.max.x -= 56;

  icon.icon_flags   =WIMP_ICON_FGCOL(7) | WIMP_ICON_TYPE(15) | \
                     WIMP_ICON_INDIRECTED_BIT | WIMP_ICON_FILLED_BIT | \
                     WIMP_ICON_VCENT_BIT | WIMP_ICON_BORDER_BIT | WIMP_ICON_TEXT_BIT;

  icon.contents.it.text      =session->line_editor_buffer;
  icon.contents.it.validation=line_editor_buffer_indirected;
  icon.contents.it.text_len  =sizeof(session->line_editor_buffer);

  _swi(Wimp_CreateIcon, _IN(1), &icon);

  if (has_checkbox)
  {
    icon.window_handle=session->pane_handle;
    icon.min.x         =width-48;
    icon.min.y         =-48;
    icon.max.x         =width;
    icon.max.y         =0;
    icon.icon_flags    =WIMP_ICON_BGCOL(1) | WIMP_ICON_TYPE(11) | WIMP_ICON_INDIRECTED_BIT | \
                        WIMP_ICON_VCENT_BIT | WIMP_ICON_TEXT_BIT | WIMP_ICON_SPRITE_BIT;

    if ( session->line_editor_type==LINEEDIT_CHECKBOX_ON )
    {
      icon.icon_flags |= WIMP_ICON_SELECTED_BIT;
    }
    icon.contents.it.text         =line_editor_icon_text;
    icon.contents.it.validation   =line_editor_icon_sprite;
    icon.contents.it.text_len     =sizeof(line_editor_icon_text);

    _swi(Wimp_CreateIcon, _IN(1), &icon);
  }

  if ( session->line_editor_type==LINEEDIT_CHECKBOX_OFF )
    set_icon_state(session->pane_handle, 0, WIMP_ICON_DELETED_BIT, WIMP_ICON_DELETED_BIT);

}

void lineedit_free_space(struct session_struct *session, bool dont_discard)
{
  /* Note - this *must* be called if the lineeditor is turned off at any point */
  struct wimp_deletewindow_block block;

  if (session->pane_handle)
  {
    block.window_handle=session->pane_handle;

    _swix(Wimp_DeleteWindow, _IN(1), &block);
    session->pane_handle = 0;
  }

  if (!dont_discard && session->line_editor_history)
  {
    free(session->line_editor_history);
    session->line_editor_history = NULL;
  }
}
