/* TUI data manipulation routines.

   Copyright (C) 1998-2004, 2006-2012 Free Software Foundation, Inc.

   Contributed by Hewlett-Packard Company.

   This file is part of GDB.

   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 3 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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "symtab.h"
#include "tui/tui.h"
#include "tui/tui-data.h"
#include "tui/tui-wingeneral.h"

#include "gdb_string.h"
#include "gdb_curses.h"

/****************************
** GLOBAL DECLARATIONS
****************************/
struct tui_win_info *(tui_win_list[MAX_MAJOR_WINDOWS]);

/***************************
** Private data
****************************/
static enum tui_layout_type current_layout = UNDEFINED_LAYOUT;
static int term_height, term_width;
static struct tui_gen_win_info _locator;
static struct tui_gen_win_info exec_info[2];
static struct tui_win_info *src_win_list[2];
static struct tui_list source_windows = {src_win_list, 0};
static int default_tab_len = DEFAULT_TAB_LEN;
static struct tui_win_info *win_with_focus = (struct tui_win_info *) NULL;
static struct tui_layout_def layout_def = {
  SRC_WIN,			/* DISPLAY_MODE */
  FALSE,			/* SPLIT */
  TUI_UNDEFINED_REGS,		/* REGS_DISPLAY_TYPE */
  TUI_SFLOAT_REGS};		/* FLOAT_REGS_DISPLAY_TYPE */

static int win_resized = FALSE;


/*********************************
** Static function forward decls
**********************************/
static void free_content (tui_win_content, 
			  int, 
			  enum tui_win_type);
static void free_content_elements (tui_win_content, 
				   int, 
				   enum tui_win_type);



/*********************************
** PUBLIC FUNCTIONS
**********************************/

int
tui_win_is_source_type (enum tui_win_type win_type)
{
  return (win_type == SRC_WIN || win_type == DISASSEM_WIN);
}

int
tui_win_is_auxillary (enum tui_win_type win_type)
{
  return (win_type > MAX_MAJOR_WINDOWS);
}

int
tui_win_has_locator (struct tui_win_info *win_info)
{
  return (win_info != NULL 
	  && win_info->detail.source_info.has_locator);
}

void
tui_set_win_highlight (struct tui_win_info *win_info, 
		       int highlight)
{
  if (win_info != NULL)
    win_info->is_highlighted = highlight;
}

/******************************************
** ACCESSORS & MUTATORS FOR PRIVATE DATA
******************************************/

/* Answer a whether the terminal window has been resized or not.  */
int
tui_win_resized (void)
{
  return win_resized;
}


/* Set a whether the terminal window has been resized or not.  */
void
tui_set_win_resized_to (int resized)
{
  win_resized = resized;
}


/* Answer a pointer to the current layout definition.  */
struct tui_layout_def *
tui_layout_def (void)
{
  return &layout_def;
}


/* Answer the window with the logical focus.  */
struct tui_win_info *
tui_win_with_focus (void)
{
  return win_with_focus;
}


/* Set the window that has the logical focus.  */
void
tui_set_win_with_focus (struct tui_win_info *win_info)
{
  win_with_focus = win_info;
}


/* Answer the length in chars, of tabs.  */
int
tui_default_tab_len (void)
{
  return default_tab_len;
}


/* Set the length in chars, of tabs.  */
void
tui_set_default_tab_len (int len)
{
  default_tab_len = len;
}


/* Accessor for the current source window.  Usually there is only one
   source window (either source or disassembly), but both can be
   displayed at the same time.  */
struct tui_list *
tui_source_windows (void)
{
  return &source_windows;
}


/* Clear the list of source windows.  Usually there is only one source
   window (either source or disassembly), but both can be displayed at
   the same time.  */
void
tui_clear_source_windows (void)
{
  source_windows.list[0] = NULL;
  source_windows.list[1] = NULL;
  source_windows.count = 0;
}


/* Clear the pertinant detail in the source windows.  */
void
tui_clear_source_windows_detail (void)
{
  int i;

  for (i = 0; i < (tui_source_windows ())->count; i++)
    tui_clear_win_detail ((tui_source_windows ())->list[i]);
}


/* Add a window to the list of source windows.  Usually there is only
   one source window (either source or disassembly), but both can be
   displayed at the same time.  */
void
tui_add_to_source_windows (struct tui_win_info *win_info)
{
  if (source_windows.count < 2)
    source_windows.list[source_windows.count++] = (void *) win_info;
}


/* Clear the pertinant detail in the windows.  */
void
tui_clear_win_detail (struct tui_win_info *win_info)
{
  if (win_info != NULL)
    {
      switch (win_info->generic.type)
	{
	case SRC_WIN:
	case DISASSEM_WIN:
	  win_info->detail.source_info.gdbarch = NULL;
	  win_info->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS;
	  win_info->detail.source_info.start_line_or_addr.u.addr = 0;
	  win_info->detail.source_info.horizontal_offset = 0;
	  break;
	case CMD_WIN:
	  win_info->detail.command_info.cur_line =
	    win_info->detail.command_info.curch = 0;
	  break;
	case DATA_WIN:
	  win_info->detail.data_display_info.data_content =
	    (tui_win_content) NULL;
	  win_info->detail.data_display_info.data_content_count = 0;
	  win_info->detail.data_display_info.regs_content =
	    (tui_win_content) NULL;
	  win_info->detail.data_display_info.regs_content_count = 0;
	  win_info->detail.data_display_info.regs_display_type =
	    TUI_UNDEFINED_REGS;
	  win_info->detail.data_display_info.regs_column_count = 1;
	  win_info->detail.data_display_info.display_regs = FALSE;
	  break;
	default:
	  break;
	}
    }
}


/* Accessor for the source execution info ptr.  */
struct tui_gen_win_info *
tui_source_exec_info_win_ptr (void)
{
  return &exec_info[0];
}


/* Accessor for the disassem execution info ptr.  */
struct tui_gen_win_info *
tui_disassem_exec_info_win_ptr (void)
{
  return &exec_info[1];
}


/* Accessor for the locator win info.  Answers a pointer to the static
   locator win info struct.  */
struct tui_gen_win_info *
tui_locator_win_info_ptr (void)
{
  return &_locator;
}


/* Accessor for the term_height.  */
int
tui_term_height (void)
{
  return term_height;
}


/* Mutator for the term height.  */
void
tui_set_term_height_to (int h)
{
  term_height = h;
}


/* Accessor for the term_width.  */
int
tui_term_width (void)
{
  return term_width;
}


/* Mutator for the term_width.  */
void
tui_set_term_width_to (int w)
{
  term_width = w;
}


/* Accessor for the current layout.  */
enum tui_layout_type
tui_current_layout (void)
{
  return current_layout;
}


/* Mutator for the current layout.  */
void
tui_set_current_layout_to (enum tui_layout_type new_layout)
{
  current_layout = new_layout;
}


/*****************************
** OTHER PUBLIC FUNCTIONS
*****************************/


/* Answer the next window in the list, cycling back to the top if
   necessary.  */
struct tui_win_info *
tui_next_win (struct tui_win_info *cur_win)
{
  enum tui_win_type type = cur_win->generic.type;
  struct tui_win_info *next_win = (struct tui_win_info *) NULL;

  if (cur_win->generic.type == CMD_WIN)
    type = SRC_WIN;
  else
    type = cur_win->generic.type + 1;
  while (type != cur_win->generic.type && (next_win == NULL))
    {
      if (tui_win_list[type]
	  && tui_win_list[type]->generic.is_visible)
	next_win = tui_win_list[type];
      else
	{
	  if (type == CMD_WIN)
	    type = SRC_WIN;
	  else
	    type++;
	}
    }

  return next_win;
}


/* Answer the prev window in the list, cycling back to the bottom if
   necessary.  */
struct tui_win_info *
tui_prev_win (struct tui_win_info *cur_win)
{
  enum tui_win_type type = cur_win->generic.type;
  struct tui_win_info *prev = (struct tui_win_info *) NULL;

  if (cur_win->generic.type == SRC_WIN)
    type = CMD_WIN;
  else
    type = cur_win->generic.type - 1;
  while (type != cur_win->generic.type && (prev == NULL))
    {
      if (tui_win_list[type]
	  && tui_win_list[type]->generic.is_visible)
	prev = tui_win_list[type];
      else
	{
	  if (type == SRC_WIN)
	    type = CMD_WIN;
	  else
	    type--;
	}
    }

  return prev;
}


/* Answer the window represented by name.  */
struct tui_win_info *
tui_partial_win_by_name (char *name)
{
  struct tui_win_info *win_info = (struct tui_win_info *) NULL;

  if (name != (char *) NULL)
    {
      int i = 0;

      while (i < MAX_MAJOR_WINDOWS && win_info == NULL)
	{
          if (tui_win_list[i] != 0)
            {
              char *cur_name = tui_win_name (&tui_win_list[i]->generic);

              if (strlen (name) <= strlen (cur_name)
		  && strncmp (name, cur_name, strlen (name)) == 0)
                win_info = tui_win_list[i];
            }
	  i++;
	}
    }

  return win_info;
}


/* Answer the name of the window.  */
char *
tui_win_name (struct tui_gen_win_info *win_info)
{
  char *name = (char *) NULL;

  switch (win_info->type)
    {
    case SRC_WIN:
      name = SRC_NAME;
      break;
    case CMD_WIN:
      name = CMD_NAME;
      break;
    case DISASSEM_WIN:
      name = DISASSEM_NAME;
      break;
    case DATA_WIN:
      name = DATA_NAME;
      break;
    default:
      name = "";
      break;
    }

  return name;
}


void
tui_initialize_static_data (void)
{
  tui_init_generic_part (tui_source_exec_info_win_ptr ());
  tui_init_generic_part (tui_disassem_exec_info_win_ptr ());
  tui_init_generic_part (tui_locator_win_info_ptr ());
}


struct tui_gen_win_info *
tui_alloc_generic_win_info (void)
{
  struct tui_gen_win_info *win;

  if ((win = XMALLOC (struct tui_gen_win_info)) != NULL)
    tui_init_generic_part (win);

  return win;
}


void
tui_init_generic_part (struct tui_gen_win_info *win)
{
  win->width =
    win->height =
    win->origin.x =
    win->origin.y =
    win->viewport_height =
    win->content_size =
    win->last_visible_line = 0;
  win->handle = (WINDOW *) NULL;
  win->content = NULL;
  win->content_in_use =
    win->is_visible = FALSE;
  win->title = 0;
}


/* init_content_element().
 */
static void
init_content_element (struct tui_win_element *element, 
		      enum tui_win_type type)
{
  element->highlight = FALSE;
  switch (type)
    {
    case SRC_WIN:
    case DISASSEM_WIN:
      element->which_element.source.line = (char *) NULL;
      element->which_element.source.line_or_addr.loa = LOA_LINE;
      element->which_element.source.line_or_addr.u.line_no = 0;
      element->which_element.source.is_exec_point = FALSE;
      element->which_element.source.has_break = FALSE;
      break;
    case DATA_WIN:
      tui_init_generic_part (&element->which_element.data_window);
      element->which_element.data_window.type = DATA_ITEM_WIN;
      ((struct tui_gen_win_info *)
       &element->which_element.data_window)->content =
	(void **) tui_alloc_content (1, DATA_ITEM_WIN);
      ((struct tui_gen_win_info *)
       & element->which_element.data_window)->content_size = 1;
      break;
    case CMD_WIN:
      element->which_element.command.line = (char *) NULL;
      break;
    case DATA_ITEM_WIN:
      element->which_element.data.name = (char *) NULL;
      element->which_element.data.type = TUI_REGISTER;
      element->which_element.data.item_no = UNDEFINED_ITEM;
      element->which_element.data.value = NULL;
      element->which_element.data.highlight = FALSE;
      element->which_element.data.content = (char*) NULL;
      break;
    case LOCATOR_WIN:
      element->which_element.locator.file_name[0] =
	element->which_element.locator.proc_name[0] = (char) 0;
      element->which_element.locator.line_no = 0;
      element->which_element.locator.addr = 0;
      break;
    case EXEC_INFO_WIN:
      memset(element->which_element.simple_string, ' ',
             sizeof(element->which_element.simple_string));
      break;
    default:
      break;
    }
}

static void
init_win_info (struct tui_win_info *win_info)
{
  tui_init_generic_part (&win_info->generic);
  win_info->can_highlight =
    win_info->is_highlighted = FALSE;
  switch (win_info->generic.type)
    {
    case SRC_WIN:
    case DISASSEM_WIN:
      win_info->detail.source_info.execution_info
	= (struct tui_gen_win_info *) NULL;
      win_info->detail.source_info.has_locator = FALSE;
      win_info->detail.source_info.horizontal_offset = 0;
      win_info->detail.source_info.gdbarch = NULL;
      win_info->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS;
      win_info->detail.source_info.start_line_or_addr.u.addr = 0;
      win_info->detail.source_info.filename = 0;
      break;
    case DATA_WIN:
      win_info->detail.data_display_info.data_content = (tui_win_content) NULL;
      win_info->detail.data_display_info.data_content_count = 0;
      win_info->detail.data_display_info.regs_content = (tui_win_content) NULL;
      win_info->detail.data_display_info.regs_content_count = 0;
      win_info->detail.data_display_info.regs_display_type =
	TUI_UNDEFINED_REGS;
      win_info->detail.data_display_info.regs_column_count = 1;
      win_info->detail.data_display_info.display_regs = FALSE;
      win_info->detail.data_display_info.current_group = 0;
      break;
    case CMD_WIN:
      win_info->detail.command_info.cur_line = 0;
      win_info->detail.command_info.curch = 0;
      break;
    default:
      win_info->detail.opaque = NULL;
      break;
    }
}


struct tui_win_info *
tui_alloc_win_info (enum tui_win_type type)
{
  struct tui_win_info *win_info;

  win_info = XMALLOC (struct tui_win_info);
  if (win_info != NULL)
    {
      win_info->generic.type = type;
      init_win_info (win_info);
    }

  return win_info;
}


/* Allocates the content and elements in a block.  */
tui_win_content
tui_alloc_content (int num_elements, enum tui_win_type type)
{
  tui_win_content content;
  char *element_block_ptr;
  int i;

  content = xmalloc (sizeof (struct tui_win_element *) *num_elements);
  if (content != NULL)
    {
      /*
       * All windows, except the data window, can allocate the
       * elements in a chunk.  The data window cannot because items
       * can be added/removed from the data display by the user at any
       * time.
       */
      if (type != DATA_WIN)
	{
	  element_block_ptr =
	    xmalloc (sizeof (struct tui_win_element) * num_elements);
	  if (element_block_ptr != NULL)
	    {
	      for (i = 0; i < num_elements; i++)
		{
		  content[i] = (struct tui_win_element *) element_block_ptr;
		  init_content_element (content[i], type);
		  element_block_ptr += sizeof (struct tui_win_element);
		}
	    }
	  else
	    {
	      xfree (content);
	      content = (tui_win_content) NULL;
	    }
	}
    }

  return content;
}


/* Adds the input number of elements to the windows's content.  If no
   content has been allocated yet, alloc_content() is called to do
   this.  The index of the first element added is returned, unless
   there is a memory allocation error, in which case, (-1) is
   returned.  */
int
tui_add_content_elements (struct tui_gen_win_info *win_info, 
			  int num_elements)
{
  struct tui_win_element *element_ptr;
  int i, index_start;

  if (win_info->content == NULL)
    {
      win_info->content = (void **) tui_alloc_content (num_elements,
						       win_info->type);
      index_start = 0;
    }
  else
    index_start = win_info->content_size;
  if (win_info->content != NULL)
    {
      for (i = index_start; (i < num_elements + index_start); i++)
	{
	  if ((element_ptr = XMALLOC (struct tui_win_element)) != NULL)
	    {
	      win_info->content[i] = (void *) element_ptr;
	      init_content_element (element_ptr, win_info->type);
	      win_info->content_size++;
	    }
	  else	/* Things must be really hosed now!  We ran out of
		   memory!?  */
	    return (-1);
	}
    }

  return index_start;
}


/* Delete all curses windows associated with win_info, leaving
   everything else intact.  */
void
tui_del_window (struct tui_win_info *win_info)
{
  struct tui_gen_win_info *generic_win;

  switch (win_info->generic.type)
    {
    case SRC_WIN:
    case DISASSEM_WIN:
      generic_win = tui_locator_win_info_ptr ();
      if (generic_win != (struct tui_gen_win_info *) NULL)
	{
	  tui_delete_win (generic_win->handle);
	  generic_win->handle = (WINDOW *) NULL;
	  generic_win->is_visible = FALSE;
	}
      if (win_info->detail.source_info.filename)
        {
          xfree (win_info->detail.source_info.filename);
          win_info->detail.source_info.filename = 0;
        }
      generic_win = win_info->detail.source_info.execution_info;
      if (generic_win != (struct tui_gen_win_info *) NULL)
	{
	  tui_delete_win (generic_win->handle);
	  generic_win->handle = (WINDOW *) NULL;
	  generic_win->is_visible = FALSE;
	}
      break;
    case DATA_WIN:
      if (win_info->generic.content != NULL)
	{
	  tui_del_data_windows (win_info->detail.data_display_info.regs_content,
				win_info->detail.data_display_info.regs_content_count);
	  tui_del_data_windows (win_info->detail.data_display_info.data_content,
				win_info->detail.data_display_info.data_content_count);
	}
      break;
    default:
      break;
    }
  if (win_info->generic.handle != (WINDOW *) NULL)
    {
      tui_delete_win (win_info->generic.handle);
      win_info->generic.handle = (WINDOW *) NULL;
      win_info->generic.is_visible = FALSE;
    }
}


void
tui_free_window (struct tui_win_info *win_info)
{
  struct tui_gen_win_info *generic_win;

  switch (win_info->generic.type)
    {
    case SRC_WIN:
    case DISASSEM_WIN:
      generic_win = tui_locator_win_info_ptr ();
      if (generic_win != (struct tui_gen_win_info *) NULL)
	{
	  tui_delete_win (generic_win->handle);
	  generic_win->handle = (WINDOW *) NULL;
	}
      tui_free_win_content (generic_win);
      if (win_info->detail.source_info.filename)
        {
          xfree (win_info->detail.source_info.filename);
          win_info->detail.source_info.filename = 0;
        }
      generic_win = win_info->detail.source_info.execution_info;
      if (generic_win != (struct tui_gen_win_info *) NULL)
	{
	  tui_delete_win (generic_win->handle);
	  generic_win->handle = (WINDOW *) NULL;
	  tui_free_win_content (generic_win);
	}
      break;
    case DATA_WIN:
      if (win_info->generic.content != NULL)
	{
	  tui_free_data_content (win_info->detail.data_display_info.regs_content,
				 win_info->detail.data_display_info.regs_content_count);
	  win_info->detail.data_display_info.regs_content =
	    (tui_win_content) NULL;
	  win_info->detail.data_display_info.regs_content_count = 0;
	  tui_free_data_content (win_info->detail.data_display_info.data_content,
				 win_info->detail.data_display_info.data_content_count);
	  win_info->detail.data_display_info.data_content =
	    (tui_win_content) NULL;
	  win_info->detail.data_display_info.data_content_count = 0;
	  win_info->detail.data_display_info.regs_display_type =
	    TUI_UNDEFINED_REGS;
	  win_info->detail.data_display_info.regs_column_count = 1;
	  win_info->detail.data_display_info.display_regs = FALSE;
	  win_info->generic.content = NULL;
	  win_info->generic.content_size = 0;
	}
      break;
    default:
      break;
    }
  if (win_info->generic.handle != (WINDOW *) NULL)
    {
      tui_delete_win (win_info->generic.handle);
      win_info->generic.handle = (WINDOW *) NULL;
      tui_free_win_content (&win_info->generic);
    }
  if (win_info->generic.title)
    xfree (win_info->generic.title);
  xfree (win_info);
}


void
tui_free_all_source_wins_content (void)
{
  int i;

  for (i = 0; i < (tui_source_windows ())->count; i++)
    {
      struct tui_win_info *win_info = (tui_source_windows ())->list[i];

      if (win_info != NULL)
	{
	  tui_free_win_content (&(win_info->generic));
	  tui_free_win_content (win_info->detail.source_info.execution_info);
	}
    }
}


void
tui_free_win_content (struct tui_gen_win_info *win_info)
{
  if (win_info->content != NULL)
    {
      free_content ((tui_win_content) win_info->content,
		   win_info->content_size,
		   win_info->type);
      win_info->content = NULL;
    }
  win_info->content_size = 0;
}


void
tui_del_data_windows (tui_win_content content, 
		      int content_size)
{
  int i;

  /* Remember that data window content elements are of type struct
     tui_gen_win_info *, each of which whose single element is a data
     element.  */
  for (i = 0; i < content_size; i++)
    {
      struct tui_gen_win_info *generic_win
	= &content[i]->which_element.data_window;

      if (generic_win != (struct tui_gen_win_info *) NULL)
	{
	  tui_delete_win (generic_win->handle);
	  generic_win->handle = (WINDOW *) NULL;
	  generic_win->is_visible = FALSE;
	}
    }
}


void
tui_free_data_content (tui_win_content content, 
		       int content_size)
{
  int i;

  /* Remember that data window content elements are of type struct
     tui_gen_win_info *, each of which whose single element is a data
     element.  */
  for (i = 0; i < content_size; i++)
    {
      struct tui_gen_win_info *generic_win
	= &content[i]->which_element.data_window;

      if (generic_win != (struct tui_gen_win_info *) NULL)
	{
	  tui_delete_win (generic_win->handle);
	  generic_win->handle = (WINDOW *) NULL;
	  tui_free_win_content (generic_win);
	}
    }
  free_content (content,
		content_size,
		DATA_WIN);
}


/**********************************
** LOCAL STATIC FUNCTIONS        **
**********************************/


static void
free_content (tui_win_content content, 
	      int content_size, 
	      enum tui_win_type win_type)
{
  if (content != (tui_win_content) NULL)
    {
      free_content_elements (content, content_size, win_type);
      xfree (content);
    }
}


/* free_content_elements().
 */
static void
free_content_elements (tui_win_content content, 
		       int content_size, 
		       enum tui_win_type type)
{
  if (content != (tui_win_content) NULL)
    {
      int i;

      if (type == SRC_WIN || type == DISASSEM_WIN)
	{
	  /* Free whole source block.  */
	  xfree (content[0]->which_element.source.line);
	}
      else
	{
	  for (i = 0; i < content_size; i++)
	    {
	      struct tui_win_element *element;

	      element = content[i];
	      if (element != (struct tui_win_element *) NULL)
		{
		  switch (type)
		    {
		    case DATA_WIN:
		      xfree (element);
		      break;
		    case DATA_ITEM_WIN:
		      /* Note that data elements are not allocated in
		         a single block, but individually, as
		         needed.  */
		      if (element->which_element.data.type != TUI_REGISTER)
			xfree ((void *)element->which_element.data.name);
		      xfree (element->which_element.data.value);
                      xfree (element->which_element.data.content);
		      xfree (element);
		      break;
		    case CMD_WIN:
		      xfree (element->which_element.command.line);
		      break;
		    default:
		      break;
		    }
		}
	    }
	}
      if (type != DATA_WIN && type != DATA_ITEM_WIN)
	xfree (content[0]);	/* Free the element block.  */
    }
}
