/* TUI display source/assembly window.

   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008,
   2009, 2010 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 <ctype.h>
#include "symtab.h"
#include "frame.h"
#include "breakpoint.h"
#include "value.h"
#include "source.h"
#include "objfiles.h"

#include "tui/tui.h"
#include "tui/tui-data.h"
#include "tui/tui-stack.h"
#include "tui/tui-win.h"
#include "tui/tui-wingeneral.h"
#include "tui/tui-winsource.h"
#include "tui/tui-source.h"
#include "tui/tui-disasm.h"

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

/* Function to display the "main" routine.  */
void
tui_display_main (void)
{
  if ((tui_source_windows ())->count > 0)
    {
      struct gdbarch *gdbarch;
      CORE_ADDR addr;

      tui_get_begin_asm_address (&gdbarch, &addr);
      if (addr != (CORE_ADDR) 0)
	{
	  struct symtab_and_line sal;

	  tui_update_source_windows_with_addr (gdbarch, addr);
	  sal = find_pc_line (addr, 0);
          if (sal.symtab)
             tui_update_locator_filename (sal.symtab->filename);
          else
             tui_update_locator_filename ("??");
	}
    }
}



/* Function to display source in the source window.  This function
   initializes the horizontal scroll to 0.  */
void
tui_update_source_window (struct tui_win_info *win_info,
			  struct gdbarch *gdbarch,
			  struct symtab *s,
			  struct tui_line_or_address line_or_addr,
			  int noerror)
{
  win_info->detail.source_info.horizontal_offset = 0;
  tui_update_source_window_as_is (win_info, gdbarch, s, line_or_addr, noerror);

  return;
}


/* Function to display source in the source/asm window.  This function
   shows the source as specified by the horizontal offset.  */
void
tui_update_source_window_as_is (struct tui_win_info *win_info, 
				struct gdbarch *gdbarch,
				struct symtab *s,
				struct tui_line_or_address line_or_addr, 
				int noerror)
{
  enum tui_status ret;

  if (win_info->generic.type == SRC_WIN)
    ret = tui_set_source_content (s, line_or_addr.u.line_no, noerror);
  else
    ret = tui_set_disassem_content (gdbarch, line_or_addr.u.addr);

  if (ret == TUI_FAILURE)
    {
      tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
      tui_clear_exec_info_content (win_info);
    }
  else
    {
      tui_update_breakpoint_info (win_info, 0);
      tui_show_source_content (win_info);
      tui_update_exec_info (win_info);
      if (win_info->generic.type == SRC_WIN)
	{
	  struct symtab_and_line sal;
	  
	  sal.line = line_or_addr.u.line_no +
	    (win_info->generic.content_size - 2);
	  sal.symtab = s;
	  set_current_source_symtab_and_line (&sal);
	  /* If the focus was in the asm win, put it in the src win if
	     we don't have a split layout.  */
	  if (tui_win_with_focus () == TUI_DISASM_WIN
	      && tui_current_layout () != SRC_DISASSEM_COMMAND)
	    tui_set_win_focus_to (TUI_SRC_WIN);
	}
    }


  return;
}


/* Function to ensure that the source and/or disassemly windows
   reflect the input address.  */
void
tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  if (addr != 0)
    {
      struct symtab_and_line sal;
      struct tui_line_or_address l;
      
      switch (tui_current_layout ())
	{
	case DISASSEM_COMMAND:
	case DISASSEM_DATA_COMMAND:
	  tui_show_disassem (gdbarch, addr);
	  break;
	case SRC_DISASSEM_COMMAND:
	  tui_show_disassem_and_update_source (gdbarch, addr);
	  break;
	default:
	  sal = find_pc_line (addr, 0);
	  l.loa = LOA_LINE;
	  l.u.line_no = sal.line;
	  tui_show_symtab_source (gdbarch, sal.symtab, l, FALSE);
	  break;
	}
    }
  else
    {
      int i;

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

	  tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
	  tui_clear_exec_info_content (win_info);
	}
    }
}

/* Function to ensure that the source and/or disassemly windows
   reflect the input address.  */
void
tui_update_source_windows_with_line (struct symtab *s, int line)
{
  struct gdbarch *gdbarch;
  CORE_ADDR pc;
  struct tui_line_or_address l;

  if (!s)
    return;

  gdbarch = get_objfile_arch (s->objfile);

  switch (tui_current_layout ())
    {
    case DISASSEM_COMMAND:
    case DISASSEM_DATA_COMMAND:
      find_line_pc (s, line, &pc);
      tui_update_source_windows_with_addr (gdbarch, pc);
      break;
    default:
      l.loa = LOA_LINE;
      l.u.line_no = line;
      tui_show_symtab_source (gdbarch, s, l, FALSE);
      if (tui_current_layout () == SRC_DISASSEM_COMMAND)
	{
	  find_line_pc (s, line, &pc);
	  tui_show_disassem (gdbarch, pc);
	}
      break;
    }

  return;
}

void
tui_clear_source_content (struct tui_win_info *win_info, 
			  int display_prompt)
{
  if (win_info != NULL)
    {
      int i;

      win_info->generic.content_in_use = FALSE;
      tui_erase_source_content (win_info, display_prompt);
      for (i = 0; i < win_info->generic.content_size; i++)
	{
	  struct tui_win_element *element =
	  (struct tui_win_element *) win_info->generic.content[i];
	  element->which_element.source.has_break = FALSE;
	  element->which_element.source.is_exec_point = FALSE;
	}
    }
}


void
tui_erase_source_content (struct tui_win_info *win_info, 
			  int display_prompt)
{
  int x_pos;
  int half_width = (win_info->generic.width - 2) / 2;

  if (win_info->generic.handle != (WINDOW *) NULL)
    {
      werase (win_info->generic.handle);
      tui_check_and_display_highlight_if_needed (win_info);
      if (display_prompt == EMPTY_SOURCE_PROMPT)
	{
	  char *no_src_str;

	  if (win_info->generic.type == SRC_WIN)
	    no_src_str = NO_SRC_STRING;
	  else
	    no_src_str = NO_DISASSEM_STRING;
	  if (strlen (no_src_str) >= half_width)
	    x_pos = 1;
	  else
	    x_pos = half_width - strlen (no_src_str);
	  mvwaddstr (win_info->generic.handle,
		     (win_info->generic.height / 2),
		     x_pos,
		     no_src_str);

	  /* elz: Added this function call to set the real contents of
	     the window to what is on the screen, so that later calls
	     to refresh, do display the correct stuff, and not the old
	     image.  */

	  tui_set_source_content_nil (win_info, no_src_str);
	}
      tui_refresh_win (&win_info->generic);
    }
}


/* Redraw the complete line of a source or disassembly window.  */
static void
tui_show_source_line (struct tui_win_info *win_info, int lineno)
{
  struct tui_win_element *line;
  int x, y;

  line = (struct tui_win_element *) win_info->generic.content[lineno - 1];
  if (line->which_element.source.is_exec_point)
    wattron (win_info->generic.handle, A_STANDOUT);

  mvwaddstr (win_info->generic.handle, lineno, 1,
             line->which_element.source.line);
  if (line->which_element.source.is_exec_point)
    wattroff (win_info->generic.handle, A_STANDOUT);

  /* Clear to end of line but stop before the border.  */
  getyx (win_info->generic.handle, y, x);
  while (x + 1 < win_info->generic.width)
    {
      waddch (win_info->generic.handle, ' ');
      getyx (win_info->generic.handle, y, x);
    }
}

void
tui_show_source_content (struct tui_win_info *win_info)
{
  if (win_info->generic.content_size > 0)
    {
      int lineno;

      for (lineno = 1; lineno <= win_info->generic.content_size; lineno++)
        tui_show_source_line (win_info, lineno);
    }
  else
    tui_erase_source_content (win_info, TRUE);

  tui_check_and_display_highlight_if_needed (win_info);
  tui_refresh_win (&win_info->generic);
  win_info->generic.content_in_use = TRUE;
}


/* Scroll the source forward or backward horizontally.  */
void
tui_horizontal_source_scroll (struct tui_win_info *win_info,
			      enum tui_scroll_direction direction,
			      int num_to_scroll)
{
  if (win_info->generic.content != NULL)
    {
      struct gdbarch *gdbarch = win_info->detail.source_info.gdbarch;
      int offset;
      struct symtab *s = NULL;

      if (win_info->generic.type == SRC_WIN)
	{
	  struct symtab_and_line cursal = get_current_source_symtab_and_line ();
	  if (cursal.symtab == NULL)
	    s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
	  else
	    s = cursal.symtab;
	}

      if (direction == LEFT_SCROLL)
	offset = win_info->detail.source_info.horizontal_offset + num_to_scroll;
      else
	{
	  if ((offset =
	     win_info->detail.source_info.horizontal_offset - num_to_scroll) < 0)
	    offset = 0;
	}
      win_info->detail.source_info.horizontal_offset = offset;
      tui_update_source_window_as_is (win_info, gdbarch, s,
				      ((struct tui_win_element *)
				       win_info->generic.content[0])->which_element.source.line_or_addr,
				      FALSE);
    }

  return;
}


/* Set or clear the has_break flag in the line whose line is
   line_no.  */

void
tui_set_is_exec_point_at (struct tui_line_or_address l, 
			  struct tui_win_info *win_info)
{
  int changed = 0;
  int i;
  tui_win_content content = (tui_win_content) win_info->generic.content;

  i = 0;
  while (i < win_info->generic.content_size)
    {
      int new_state;
      struct tui_line_or_address content_loa =
	content[i]->which_element.source.line_or_addr;

      gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
      gdb_assert (content_loa.loa == LOA_LINE
		  || content_loa.loa == LOA_ADDRESS);
      if (content_loa.loa == l.loa
	  && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
              || (content_loa.u.addr == l.u.addr)))
        new_state = TRUE;
      else
	new_state = FALSE;
      if (new_state != content[i]->which_element.source.is_exec_point)
        {
          changed++;
          content[i]->which_element.source.is_exec_point = new_state;
          tui_show_source_line (win_info, i + 1);
        }
      i++;
    }
  if (changed)
    tui_refresh_win (&win_info->generic);
}

/* Update the execution windows to show the active breakpoints.
   This is called whenever a breakpoint is inserted, removed or
   has its state changed.  */
void
tui_update_all_breakpoint_info (void)
{
  struct tui_list *list = tui_source_windows ();
  int i;

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

      if (tui_update_breakpoint_info (win, FALSE))
        {
          tui_update_exec_info (win);
        }
    }
}


/* Scan the source window and the breakpoints to update the has_break
   information for each line.

   Returns 1 if something changed and the execution window must be
   refreshed.  */

int
tui_update_breakpoint_info (struct tui_win_info *win, 
			    int current_only)
{
  int i;
  int need_refresh = 0;
  struct tui_source_info *src = &win->detail.source_info;

  for (i = 0; i < win->generic.content_size; i++)
    {
      struct breakpoint *bp;
      extern struct breakpoint *breakpoint_chain;
      int mode;
      struct tui_source_element *line;

      line = &((struct tui_win_element *) win->generic.content[i])->which_element.source;
      if (current_only && !line->is_exec_point)
         continue;

      /* Scan each breakpoint to see if the current line has something to
         do with it.  Identify enable/disabled breakpoints as well as
         those that we already hit.  */
      mode = 0;
      for (bp = breakpoint_chain;
           bp != (struct breakpoint *) NULL;
           bp = bp->next)
        {
	  gdb_assert (line->line_or_addr.loa == LOA_LINE
		      || line->line_or_addr.loa == LOA_ADDRESS);
          if ((win == TUI_SRC_WIN
               && bp->source_file
               && (strcmp (src->filename, bp->source_file) == 0)
	       && line->line_or_addr.loa == LOA_LINE
               && bp->line_number == line->line_or_addr.u.line_no)
              || (win == TUI_DISASM_WIN
		  && line->line_or_addr.loa == LOA_ADDRESS
		  && bp->loc != NULL
                  && bp->loc->address == line->line_or_addr.u.addr))
            {
              if (bp->enable_state == bp_disabled)
                mode |= TUI_BP_DISABLED;
              else
                mode |= TUI_BP_ENABLED;
              if (bp->hit_count)
                mode |= TUI_BP_HIT;
              if (bp->loc->cond)
                mode |= TUI_BP_CONDITIONAL;
              if (bp->type == bp_hardware_breakpoint)
                mode |= TUI_BP_HARDWARE;
            }
        }
      if (line->has_break != mode)
        {
          line->has_break = mode;
          need_refresh = 1;
        }
    }
  return need_refresh;
}


/* Function to initialize the content of the execution info window,
   based upon the input window which is either the source or
   disassembly window.  */
enum tui_status
tui_set_exec_info_content (struct tui_win_info *win_info)
{
  enum tui_status ret = TUI_SUCCESS;

  if (win_info->detail.source_info.execution_info != (struct tui_gen_win_info *) NULL)
    {
      struct tui_gen_win_info *exec_info_ptr = win_info->detail.source_info.execution_info;

      if (exec_info_ptr->content == NULL)
	exec_info_ptr->content =
	  (void **) tui_alloc_content (win_info->generic.height,
					 exec_info_ptr->type);
      if (exec_info_ptr->content != NULL)
	{
	  int i;

          tui_update_breakpoint_info (win_info, 1);
	  for (i = 0; i < win_info->generic.content_size; i++)
	    {
	      struct tui_win_element *element;
	      struct tui_win_element *src_element;
              int mode;

	      element = (struct tui_win_element *) exec_info_ptr->content[i];
	      src_element = (struct tui_win_element *) win_info->generic.content[i];

              memset(element->which_element.simple_string, ' ',
                     sizeof(element->which_element.simple_string));
              element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0;

	      /* Now update the exec info content based upon the state
                 of each line as indicated by the source content.  */
              mode = src_element->which_element.source.has_break;
              if (mode & TUI_BP_HIT)
                element->which_element.simple_string[TUI_BP_HIT_POS] =
                  (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
              else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
                element->which_element.simple_string[TUI_BP_HIT_POS] =
                  (mode & TUI_BP_HARDWARE) ? 'h' : 'b';

              if (mode & TUI_BP_ENABLED)
                element->which_element.simple_string[TUI_BP_BREAK_POS] = '+';
              else if (mode & TUI_BP_DISABLED)
                element->which_element.simple_string[TUI_BP_BREAK_POS] = '-';

              if (src_element->which_element.source.is_exec_point)
                element->which_element.simple_string[TUI_EXEC_POS] = '>';
	    }
	  exec_info_ptr->content_size = win_info->generic.content_size;
	}
      else
	ret = TUI_FAILURE;
    }

  return ret;
}


void
tui_show_exec_info_content (struct tui_win_info *win_info)
{
  struct tui_gen_win_info *exec_info = win_info->detail.source_info.execution_info;
  int cur_line;

  werase (exec_info->handle);
  tui_refresh_win (exec_info);
  for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
    mvwaddstr (exec_info->handle,
	       cur_line,
	       0,
	       ((struct tui_win_element *)
		exec_info->content[cur_line - 1])->which_element.simple_string);
  tui_refresh_win (exec_info);
  exec_info->content_in_use = TRUE;
}


void
tui_erase_exec_info_content (struct tui_win_info *win_info)
{
  struct tui_gen_win_info *exec_info = win_info->detail.source_info.execution_info;

  werase (exec_info->handle);
  tui_refresh_win (exec_info);
}

void
tui_clear_exec_info_content (struct tui_win_info *win_info)
{
  win_info->detail.source_info.execution_info->content_in_use = FALSE;
  tui_erase_exec_info_content (win_info);

  return;
}

/* Function to update the execution info window.  */
void
tui_update_exec_info (struct tui_win_info *win_info)
{
  tui_set_exec_info_content (win_info);
  tui_show_exec_info_content (win_info);
}

enum tui_status
tui_alloc_source_buffer (struct tui_win_info *win_info)
{
  char *src_line_buf;
  int i, line_width, max_lines;

  max_lines = win_info->generic.height;	/* Less the highlight box.  */
  line_width = win_info->generic.width - 1;
  /*
   * Allocate the buffer for the source lines.  Do this only once
   * since they will be re-used for all source displays.  The only
   * other time this will be done is when a window's size changes.
   */
  if (win_info->generic.content == NULL)
    {
      src_line_buf = (char *) 
	xmalloc ((max_lines * line_width) * sizeof (char));
      if (src_line_buf == (char *) NULL)
	{
	  fputs_unfiltered ("Unable to Allocate Memory for Source or Disassembly Display.\n",
			    gdb_stderr);
	  return TUI_FAILURE;
	}
      /* Allocate the content list.  */
      if ((win_info->generic.content =
	   (void **) tui_alloc_content (max_lines, SRC_WIN)) == NULL)
	{
	  xfree (src_line_buf);
	  fputs_unfiltered ("Unable to Allocate Memory for Source or Disassembly Display.\n",
			    gdb_stderr);
	  return TUI_FAILURE;
	}
      for (i = 0; i < max_lines; i++)
	((struct tui_win_element *)
	 win_info->generic.content[i])->which_element.source.line =
	  src_line_buf + (line_width * i);
    }

  return TUI_SUCCESS;
}


/* Answer whether the a particular line number or address is displayed
   in the current source window.  */
int
tui_line_is_displayed (int line, 
		       struct tui_win_info *win_info,
		       int check_threshold)
{
  int is_displayed = FALSE;
  int i, threshold;

  if (check_threshold)
    threshold = SCROLL_THRESHOLD;
  else
    threshold = 0;
  i = 0;
  while (i < win_info->generic.content_size - threshold
	 && !is_displayed)
    {
      is_displayed = (((struct tui_win_element *)
		       win_info->generic.content[i])->which_element.source.line_or_addr.loa
		      == LOA_LINE)
	&& (((struct tui_win_element *)
	     win_info->generic.content[i])->which_element.source.line_or_addr.u.line_no
	    == (int) line);
      i++;
    }

  return is_displayed;
}


/* Answer whether the a particular line number or address is displayed
   in the current source window.  */
int
tui_addr_is_displayed (CORE_ADDR addr, 
		       struct tui_win_info *win_info,
		       int check_threshold)
{
  int is_displayed = FALSE;
  int i, threshold;

  if (check_threshold)
    threshold = SCROLL_THRESHOLD;
  else
    threshold = 0;
  i = 0;
  while (i < win_info->generic.content_size - threshold
	 && !is_displayed)
    {
      is_displayed = (((struct tui_win_element *)
		       win_info->generic.content[i])->which_element.source.line_or_addr.loa
		      == LOA_ADDRESS)
	&& (((struct tui_win_element *)
	     win_info->generic.content[i])->which_element.source.line_or_addr.u.addr
	    == addr);
      i++;
    }

  return is_displayed;
}


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