/* TUI layout window management.

   Copyright (C) 1998-2022 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 "arch-utils.h"
#include "command.h"
#include "symtab.h"
#include "frame.h"
#include "source.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-utils.h"
#include <ctype.h>
#include <unordered_map>
#include <unordered_set>

#include "tui/tui.h"
#include "tui/tui-command.h"
#include "tui/tui-data.h"
#include "tui/tui-wingeneral.h"
#include "tui/tui-stack.h"
#include "tui/tui-regs.h"
#include "tui/tui-win.h"
#include "tui/tui-winsource.h"
#include "tui/tui-disasm.h"
#include "tui/tui-layout.h"
#include "tui/tui-source.h"
#include "gdb_curses.h"

static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);

/* The layouts.  */
static std::vector<std::unique_ptr<tui_layout_split>> layouts;

/* The layout that is currently applied.  */
static std::unique_ptr<tui_layout_base> applied_layout;

/* The "skeleton" version of the layout that is currently applied.  */
static tui_layout_split *applied_skeleton;

/* The two special "regs" layouts.  Note that these aren't registered
   as commands and so can never be deleted.  */
static tui_layout_split *src_regs_layout;
static tui_layout_split *asm_regs_layout;

/* See tui-data.h.  */
std::vector<tui_win_info *> tui_windows;

/* See tui-layout.h.  */

void
tui_apply_current_layout (bool preserve_cmd_win_size_p)
{
  struct gdbarch *gdbarch;
  CORE_ADDR addr;

  extract_display_start_addr (&gdbarch, &addr);

  for (tui_win_info *win_info : tui_windows)
    win_info->make_visible (false);

  applied_layout->apply (0, 0, tui_term_width (), tui_term_height (),
			 preserve_cmd_win_size_p);

  /* Keep the list of internal windows up-to-date.  */
  for (int win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++)
    if (tui_win_list[win_type] != nullptr
	&& !tui_win_list[win_type]->is_visible ())
      tui_win_list[win_type] = nullptr;

  /* This should always be made visible by a layout.  */
  gdb_assert (TUI_CMD_WIN != nullptr);
  gdb_assert (TUI_CMD_WIN->is_visible ());

  /* Get the new list of currently visible windows.  */
  std::vector<tui_win_info *> new_tui_windows;
  applied_layout->get_windows (&new_tui_windows);

  /* Now delete any window that was not re-applied.  */
  tui_win_info *focus = tui_win_with_focus ();
  for (tui_win_info *win_info : tui_windows)
    {
      if (!win_info->is_visible ())
	{
	  if (focus == win_info)
	    tui_set_win_focus_to (new_tui_windows[0]);
	  delete win_info;
	}
    }

  /* Replace the global list of active windows.  */
  tui_windows = std::move (new_tui_windows);

  if (gdbarch == nullptr && TUI_DISASM_WIN != nullptr)
    tui_get_begin_asm_address (&gdbarch, &addr);
  tui_update_source_windows_with_addr (gdbarch, addr);
}

/* See tui-layout.  */

void
tui_adjust_window_height (struct tui_win_info *win, int new_height)
{
  applied_layout->set_height (win->name (), new_height);
}

/* See tui-layout.  */

void
tui_adjust_window_width (struct tui_win_info *win, int new_width)
{
  applied_layout->set_width (win->name (), new_width);
}

/* Set the current layout to LAYOUT.  */

static void
tui_set_layout (tui_layout_split *layout)
{
  std::string old_fingerprint;
  if (applied_layout != nullptr)
    old_fingerprint = applied_layout->layout_fingerprint ();

  applied_skeleton = layout;
  applied_layout = layout->clone ();

  std::string new_fingerprint = applied_layout->layout_fingerprint ();
  bool preserve_command_window_size
    = (TUI_CMD_WIN != nullptr && old_fingerprint == new_fingerprint);

  tui_apply_current_layout (preserve_command_window_size);
}

/* See tui-layout.h.  */

void
tui_add_win_to_layout (enum tui_win_type type)
{
  gdb_assert (type == SRC_WIN || type == DISASSEM_WIN);

  /* If the window already exists, no need to add it.  */
  if (tui_win_list[type] != nullptr)
    return;

  /* If the window we are trying to replace doesn't exist, we're
     done.  */
  enum tui_win_type other = type == SRC_WIN ? DISASSEM_WIN : SRC_WIN;
  if (tui_win_list[other] == nullptr)
    return;

  const char *name = type == SRC_WIN ? SRC_NAME : DISASSEM_NAME;
  applied_layout->replace_window (tui_win_list[other]->name (), name);
  tui_apply_current_layout (true);
}

/* Find LAYOUT in the "layouts" global and return its index.  */

static size_t
find_layout (tui_layout_split *layout)
{
  for (size_t i = 0; i < layouts.size (); ++i)
    {
      if (layout == layouts[i].get ())
	return i;
    }
  gdb_assert_not_reached ("layout not found!?");
}

/* Function to set the layout. */

static void
tui_apply_layout (const char *args, int from_tty, cmd_list_element *command)
{
  tui_layout_split *layout = (tui_layout_split *) command->context ();

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  tui_set_layout (layout);
}

/* See tui-layout.h.  */

void
tui_next_layout ()
{
  size_t index = find_layout (applied_skeleton);
  ++index;
  if (index == layouts.size ())
    index = 0;
  tui_set_layout (layouts[index].get ());
}

/* Implement the "layout next" command.  */

static void
tui_next_layout_command (const char *arg, int from_tty)
{
  tui_enable ();
  tui_next_layout ();
}

/* See tui-layout.h.  */

void
tui_set_initial_layout ()
{
  tui_set_layout (layouts[0].get ());
}

/* Implement the "layout prev" command.  */

static void
tui_prev_layout_command (const char *arg, int from_tty)
{
  tui_enable ();
  size_t index = find_layout (applied_skeleton);
  if (index == 0)
    index = layouts.size ();
  --index;
  tui_set_layout (layouts[index].get ());
}


/* See tui-layout.h.  */

void
tui_regs_layout ()
{
  /* If there's already a register window, we're done.  */
  if (TUI_DATA_WIN != nullptr)
    return;

  tui_set_layout (TUI_DISASM_WIN != nullptr
		  ? asm_regs_layout
		  : src_regs_layout);
}

/* Implement the "layout regs" command.  */

static void
tui_regs_layout_command (const char *arg, int from_tty)
{
  tui_enable ();
  tui_regs_layout ();
}

/* See tui-layout.h.  */

void
tui_remove_some_windows ()
{
  tui_win_info *focus = tui_win_with_focus ();

  if (strcmp (focus->name (), CMD_NAME) == 0)
    {
      /* Try leaving the source or disassembly window.  If neither
	 exists, just do nothing.  */
      focus = TUI_SRC_WIN;
      if (focus == nullptr)
	focus = TUI_DISASM_WIN;
      if (focus == nullptr)
	return;
    }

  applied_layout->remove_windows (focus->name ());
  tui_apply_current_layout (true);
}

static void
extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
{
  if (TUI_SRC_WIN != nullptr)
    TUI_SRC_WIN->display_start_addr (gdbarch_p, addr_p);
  else if (TUI_DISASM_WIN != nullptr)
    TUI_DISASM_WIN->display_start_addr (gdbarch_p, addr_p);
  else
    {
      *gdbarch_p = nullptr;
      *addr_p = 0;
    }
}

void
tui_win_info::resize (int height_, int width_,
		      int origin_x_, int origin_y_)
{
  if (width == width_ && height == height_
      && x == origin_x_ && y == origin_y_
      && handle != nullptr)
    return;

  width = width_;
  height = height_;
  x = origin_x_;
  y = origin_y_;

  if (handle != nullptr)
    {
#ifdef HAVE_WRESIZE
      wresize (handle.get (), height, width);
      mvwin (handle.get (), y, x);
      wmove (handle.get (), 0, 0);
#else
      handle.reset (nullptr);
#endif
    }

  if (handle == nullptr)
    make_window ();

  rerender ();
}



/* Helper function to create one of the built-in (non-locator)
   windows.  */

template<enum tui_win_type V, class T>
static tui_win_info *
make_standard_window (const char *)
{
  if (tui_win_list[V] == nullptr)
    tui_win_list[V] = new T ();
  return tui_win_list[V];
}

/* A map holding all the known window types, keyed by name.  Note that
   this is heap-allocated and "leaked" at gdb exit.  This avoids
   ordering issues with destroying elements in the map at shutdown.
   In particular, destroying this map can occur after Python has been
   shut down, causing crashes if any window destruction requires
   running Python code.  */

static std::unordered_map<std::string, window_factory> *known_window_types;

/* Helper function that returns a TUI window, given its name.  */

static tui_win_info *
tui_get_window_by_name (const std::string &name)
{
  for (tui_win_info *window : tui_windows)
    if (name == window->name ())
      return window;

  auto iter = known_window_types->find (name);
  if (iter == known_window_types->end ())
    error (_("Unknown window type \"%s\""), name.c_str ());

  tui_win_info *result = iter->second (name.c_str ());
  if (result == nullptr)
    error (_("Could not create window \"%s\""), name.c_str ());
  return result;
}

/* Initialize the known window types.  */

static void
initialize_known_windows ()
{
  known_window_types = new std::unordered_map<std::string, window_factory>;

  known_window_types->emplace (SRC_NAME,
			       make_standard_window<SRC_WIN,
						    tui_source_window>);
  known_window_types->emplace (CMD_NAME,
			       make_standard_window<CMD_WIN, tui_cmd_window>);
  known_window_types->emplace (DATA_NAME,
			       make_standard_window<DATA_WIN,
						    tui_data_window>);
  known_window_types->emplace (DISASSEM_NAME,
			       make_standard_window<DISASSEM_WIN,
						    tui_disasm_window>);
  known_window_types->emplace (STATUS_NAME,
			       make_standard_window<STATUS_WIN,
						    tui_locator_window>);
}

/* See tui-layout.h.  */

void
tui_register_window (const char *name, window_factory &&factory)
{
  std::string name_copy = name;

  if (name_copy == SRC_NAME || name_copy == CMD_NAME || name_copy == DATA_NAME
      || name_copy == DISASSEM_NAME || name_copy == STATUS_NAME)
    error (_("Window type \"%s\" is built-in"), name);

  known_window_types->emplace (std::move (name_copy),
			       std::move (factory));
}

/* See tui-layout.h.  */

std::unique_ptr<tui_layout_base>
tui_layout_window::clone () const
{
  tui_layout_window *result = new tui_layout_window (m_contents.c_str ());
  return std::unique_ptr<tui_layout_base> (result);
}

/* See tui-layout.h.  */

void
tui_layout_window::apply (int x_, int y_, int width_, int height_,
			  bool preserve_cmd_win_size_p)
{
  x = x_;
  y = y_;
  width = width_;
  height = height_;
  gdb_assert (m_window != nullptr);
  m_window->resize (height, width, x, y);
}

/* See tui-layout.h.  */

void
tui_layout_window::get_sizes (bool height, int *min_value, int *max_value)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  if (m_window == nullptr)
    m_window = tui_get_window_by_name (m_contents);

  tui_debug_printf ("window = %s, getting %s",
		    m_window->name (), (height ? "height" : "width"));

  if (height)
    {
      *min_value = m_window->min_height ();
      *max_value = m_window->max_height ();
    }
  else
    {
      *min_value = m_window->min_width ();
      *max_value = m_window->max_width ();
    }

  tui_debug_printf ("min = %d, max = %d", *min_value, *max_value);
}

/* See tui-layout.h.  */

bool
tui_layout_window::first_edge_has_border_p () const
{
  gdb_assert (m_window != nullptr);
  return m_window->can_box ();
}

/* See tui-layout.h.  */

bool
tui_layout_window::last_edge_has_border_p () const
{
  gdb_assert (m_window != nullptr);
  return m_window->can_box ();
}

/* See tui-layout.h.  */

void
tui_layout_window::replace_window (const char *name, const char *new_window)
{
  if (m_contents == name)
    {
      m_contents = new_window;
      if (m_window != nullptr)
	{
	  m_window->make_visible (false);
	  m_window = tui_get_window_by_name (m_contents);
	}
    }
}

/* See tui-layout.h.  */

void
tui_layout_window::specification (ui_file *output, int depth)
{
  gdb_puts (get_name (), output);
}

/* See tui-layout.h.  */

std::string
tui_layout_window::layout_fingerprint () const
{
  if (strcmp (get_name (), "cmd") == 0)
    return "C";
  else
    return "";
}

/* See tui-layout.h.  */

void
tui_layout_split::add_split (std::unique_ptr<tui_layout_split> &&layout,
			     int weight)
{
  split s = {weight, std::move (layout)};
  m_splits.push_back (std::move (s));
}

/* See tui-layout.h.  */

void
tui_layout_split::add_window (const char *name, int weight)
{
  tui_layout_window *result = new tui_layout_window (name);
  split s = {weight, std::unique_ptr<tui_layout_base> (result)};
  m_splits.push_back (std::move (s));
}

/* See tui-layout.h.  */

std::unique_ptr<tui_layout_base>
tui_layout_split::clone () const
{
  tui_layout_split *result = new tui_layout_split (m_vertical);
  for (const split &item : m_splits)
    {
      std::unique_ptr<tui_layout_base> next = item.layout->clone ();
      split s = {item.weight, std::move (next)};
      result->m_splits.push_back (std::move (s));
    }
  return std::unique_ptr<tui_layout_base> (result);
}

/* See tui-layout.h.  */

void
tui_layout_split::get_sizes (bool height, int *min_value, int *max_value)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  *min_value = 0;
  *max_value = 0;
  bool first_time = true;
  for (const split &item : m_splits)
    {
      int new_min, new_max;
      item.layout->get_sizes (height, &new_min, &new_max);
      /* For the mismatch case, the first time through we want to set
	 the min and max to the computed values -- the "first_time"
	 check here is just a funny way of doing that.  */
      if (height == m_vertical || first_time)
	{
	  *min_value += new_min;
	  *max_value += new_max;
	}
      else
	{
	  *min_value = std::max (*min_value, new_min);
	  *max_value = std::min (*max_value, new_max);
	}
      first_time = false;
    }

  tui_debug_printf ("min_value = %d, max_value = %d", *min_value, *max_value);
}

/* See tui-layout.h.  */

bool
tui_layout_split::first_edge_has_border_p () const
{
  if (m_splits.empty ())
    return false;
  return m_splits[0].layout->first_edge_has_border_p ();
}

/* See tui-layout.h.  */

bool
tui_layout_split::last_edge_has_border_p () const
{
  if (m_splits.empty ())
    return false;
  return m_splits.back ().layout->last_edge_has_border_p ();
}

/* See tui-layout.h.  */

void
tui_layout_split::set_weights_from_sizes ()
{
  for (int i = 0; i < m_splits.size (); ++i)
    m_splits[i].weight
      = m_vertical ? m_splits[i].layout->height : m_splits[i].layout->width;
}

/* See tui-layout.h.  */

std::string
tui_layout_split::tui_debug_weights_to_string () const
{
  std::string str;

  for (int i = 0; i < m_splits.size (); ++i)
    {
      if (i > 0)
       str += ", ";
      str += string_printf ("[%d] %d", i, m_splits[i].weight);
    }

  return str;
}

/* See tui-layout.h.  */

void
tui_layout_split::tui_debug_print_size_info
  (const std::vector<tui_layout_split::size_info> &info)
{
  gdb_assert (debug_tui);

  tui_debug_printf ("current size info data:");
  for (int i = 0; i < info.size (); ++i)
    tui_debug_printf ("  [%d] { size = %d, min = %d, max = %d, share_box = %d }",
		      i, info[i].size, info[i].min_size,
		      info[i].max_size, info[i].share_box);
}

/* See tui-layout.h.  */

tui_adjust_result
tui_layout_split::set_size (const char *name, int new_size, bool set_width_p)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  tui_debug_printf ("this = %p, name = %s, new_size = %d",
		    this, name, new_size);

  /* Look through the children.  If one is a layout holding the named
     window, we're done; or if one actually is the named window,
     update it.  */
  int found_index = -1;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      tui_adjust_result adjusted;
      if (set_width_p)
	adjusted = m_splits[i].layout->set_width (name, new_size);
      else
	adjusted = m_splits[i].layout->set_height (name, new_size);
      if (adjusted == HANDLED)
	return HANDLED;
      if (adjusted == FOUND)
	{
	  if (set_width_p ? m_vertical : !m_vertical)
	    return FOUND;
	  found_index = i;
	  break;
	}
    }

  if (found_index == -1)
    return NOT_FOUND;
  int curr_size = (set_width_p
		   ? m_splits[found_index].layout->width
		   : m_splits[found_index].layout->height);
  if (curr_size == new_size)
    return HANDLED;

  tui_debug_printf ("found window %s at index %d", name, found_index);

  set_weights_from_sizes ();
  int delta = m_splits[found_index].weight - new_size;
  m_splits[found_index].weight = new_size;

  tui_debug_printf ("before delta (%d) distribution, weights: %s",
		    delta, tui_debug_weights_to_string ().c_str ());

  /* Distribute the "delta" over all other windows, while respecting their
     min/max sizes.  We grow each window by 1 line at a time continually
     looping over all the windows.  However, skip the window that the user
     just resized, obviously we don't want to readjust that window.  */
  bool found_window_that_can_grow_p = true;
  for (int i = 0; delta != 0; i = (i + 1) % m_splits.size ())
    {
      int index = (found_index + 1 + i) % m_splits.size ();
      if (index == found_index)
	{
	  if (!found_window_that_can_grow_p)
	    break;
	  found_window_that_can_grow_p = false;
	  continue;
	}

      int new_min, new_max;
      m_splits[index].layout->get_sizes (m_vertical, &new_min, &new_max);

      if (delta < 0)
	{
	  /* The primary window grew, so we are trying to shrink other
	     windows.  */
	  if (m_splits[index].weight > new_min)
	    {
	      m_splits[index].weight -= 1;
	      delta += 1;
	      found_window_that_can_grow_p = true;
	    }
	}
      else
	{
	  /* The primary window shrank, so we are trying to grow other
	     windows.  */
	  if (m_splits[index].weight < new_max)
	    {
	      m_splits[index].weight += 1;
	      delta -= 1;
	      found_window_that_can_grow_p = true;
	    }
	}

      tui_debug_printf ("index = %d, weight now: %d",
			index, m_splits[index].weight);
    }

  tui_debug_printf ("after delta (%d) distribution, weights: %s",
		    delta, tui_debug_weights_to_string ().c_str ());

  if (delta != 0)
    {
      if (set_width_p)
	warning (_("Invalid window width specified"));
      else
	warning (_("Invalid window height specified"));
      /* Effectively undo any modifications made here.  */
      set_weights_from_sizes ();
    }
  else
    {
      /* Simply re-apply the updated layout.  We pass false here so that
	 the cmd window can be resized.  However, we should have already
	 resized everything above to be "just right", so the apply call
	 here should not end up changing the sizes at all.  */
      apply (x, y, width, height, false);
    }

  return HANDLED;
}

/* See tui-layout.h.  */

void
tui_layout_split::apply (int x_, int y_, int width_, int height_,
			 bool preserve_cmd_win_size_p)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  x = x_;
  y = y_;
  width = width_;
  height = height_;

  /* In some situations we fix the size of the cmd window.  However,
     occasionally this turns out to be a mistake.  This struct is used to
     hold the original information about the cmd window, so we can restore
     it if needed.  */
  struct old_size_info
  {
    /* Constructor.  */
    old_size_info (int index_, int min_size_, int max_size_)
      : index (index_),
	min_size (min_size_),
	max_size (max_size_)
    { /* Nothing.  */ }

    /* The index in m_splits where the cmd window was found.  */
    int index;

    /* The previous min/max size.  */
    int min_size;
    int max_size;
  };

  /* This is given a value only if we fix the size of the cmd window.  */
  gdb::optional<old_size_info> old_cmd_info;

  std::vector<size_info> info (m_splits.size ());

  tui_debug_printf ("weights are: %s",
		    tui_debug_weights_to_string ().c_str ());

  /* Step 1: Find the min and max size of each sub-layout.
     Fixed-sized layouts are given their desired size, and then the
     remaining space is distributed among the remaining windows
     according to the weights given.  */
  int available_size = m_vertical ? height : width;
  int last_index = -1;
  int total_weight = 0;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      bool cmd_win_already_exists = TUI_CMD_WIN != nullptr;

      /* Always call get_sizes, to ensure that the window is
	 instantiated.  This is a bit gross but less gross than adding
	 special cases for this in other places.  */
      m_splits[i].layout->get_sizes (m_vertical, &info[i].min_size,
				     &info[i].max_size);

      if (preserve_cmd_win_size_p
	  && cmd_win_already_exists
	  && m_splits[i].layout->get_name () != nullptr
	  && strcmp (m_splits[i].layout->get_name (), "cmd") == 0)
	{
	  /* Save the old cmd window information, in case we need to
	     restore it later.  */
          old_cmd_info.emplace (i, info[i].min_size, info[i].max_size);

	  /* If this layout has never been applied, then it means the
	     user just changed the layout.  In this situation, it's
	     desirable to keep the size of the command window the
	     same.  Setting the min and max sizes this way ensures
	     that the resizing step, below, does the right thing with
	     this window.  */
	  info[i].min_size = (m_vertical
			      ? TUI_CMD_WIN->height
			      : TUI_CMD_WIN->width);
	  info[i].max_size = info[i].min_size;
	}

      if (info[i].min_size == info[i].max_size)
	available_size -= info[i].min_size;
      else
	{
	  last_index = i;
	  total_weight += m_splits[i].weight;
	}

      /* Two adjacent boxed windows will share a border, making a bit
	 more size available.  */
      if (i > 0
	  && m_splits[i - 1].layout->last_edge_has_border_p ()
	  && m_splits[i].layout->first_edge_has_border_p ())
	info[i].share_box = true;
    }

  /* If last_index is set then we have a window that is not of a fixed
     size.  This window will have its size calculated below, which requires
     that the total_weight not be zero (we divide by total_weight, so don't
     want a floating-point exception).  */
  gdb_assert (last_index == -1 || total_weight > 0);

  /* Step 2: Compute the size of each sub-layout.  Fixed-sized items
     are given their fixed size, while others are resized according to
     their weight.  */
  int used_size = 0;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      if (info[i].min_size != info[i].max_size)
	{
	  /* Compute the height and clamp to the allowable range.  */
	  info[i].size = available_size * m_splits[i].weight / total_weight;
	  if (info[i].size > info[i].max_size)
	    info[i].size = info[i].max_size;
	  if (info[i].size < info[i].min_size)
	    info[i].size = info[i].min_size;
	  /* Keep a total of all the size we've used so far (we gain some
	     size back if this window can share a border with a preceding
	     window).  Any unused space will be distributed between all of
	     the other windows (while respecting min/max sizes) later in
	     this function.  */
	  used_size += info[i].size;
	  if (info[i].share_box)
	    --used_size;
	}
      else
	info[i].size = info[i].min_size;
    }

  if (debug_tui)
    {
      tui_debug_printf ("after initial size calculation");
      tui_debug_printf ("available_size = %d, used_size = %d",
			available_size, used_size);
      tui_debug_printf ("total_weight = %d, last_index = %d",
			total_weight, last_index);
      tui_debug_print_size_info (info);
    }

  /* If we didn't find any sub-layouts that were of a non-fixed size, but
     we did find the cmd window, then we can consider that a sort-of
     non-fixed size sub-layout.

     The cmd window might, initially, be of a fixed size (see above), but,
     we are willing to relax this constraint if required to correctly apply
     this layout (see below).  */
  if (last_index == -1 && old_cmd_info.has_value ())
    last_index = old_cmd_info->index;

  /* Allocate any leftover size.  */
  if (available_size != used_size && last_index != -1)
    {
      /* Loop over all windows until the amount of used space is equal to
	 the amount of available space.  There's an escape hatch within
	 the loop in case we can't find any sub-layouts to resize.  */
      bool found_window_that_can_grow_p = true;
      for (int idx = last_index;
	   available_size != used_size;
	   idx = (idx + 1) % m_splits.size ())
	{
	  /* Every time we get back to last_index, which is where the loop
	     started, we check to make sure that we did assign some space
	     to a window, bringing used_size closer to available_size.

	     If we didn't, but the cmd window is of a fixed size, then we
	     can make the console window non-fixed-size, and continue
	     around the loop, hopefully, this will allow the layout to be
	     applied correctly.

	     If we still make it around the loop without moving used_size
	     closer to available_size, then there's nothing more we can do,
	     and we break out of the loop.  */
	  if (idx == last_index)
	    {
	      /* If the used_size is greater than the available_size then
		 this indicates that the fixed-sized sub-layouts claimed
		 more space than is available.  This layout is not going to
		 work.  Our only hope at this point is to make the cmd
		 window non-fixed-size (if possible), and hope we can
		 shrink this enough to fit the rest of the sub-layouts in.

	         Alternatively, we've made it around the loop without
	         adjusting any window's size.  This likely means all
	         windows have hit their min or max size.  Again, our only
	         hope is to make the cmd window non-fixed-size, and hope
	         this fixes all our problems.  */
	      if (old_cmd_info.has_value ()
		  && ((available_size < used_size)
		      || !found_window_that_can_grow_p))
		{
		  info[old_cmd_info->index].min_size = old_cmd_info->min_size;
		  info[old_cmd_info->index].max_size = old_cmd_info->max_size;
		  tui_debug_printf
		    ("restoring index %d (cmd) size limits, min = %d, max = %d",
		     old_cmd_info->index, old_cmd_info->min_size,
		     old_cmd_info->max_size);
		  old_cmd_info.reset ();
		}
	      else if (!found_window_that_can_grow_p)
		break;
	      found_window_that_can_grow_p = false;
	    }

	  if (available_size > used_size
	      && info[idx].size < info[idx].max_size)
	    {
	      found_window_that_can_grow_p = true;
	      info[idx].size += 1;
	      used_size += 1;
	    }
	  else if (available_size < used_size
		   && info[idx].size > info[idx].min_size)
	    {
	      found_window_that_can_grow_p = true;
	      info[idx].size -= 1;
	      used_size -= 1;
	    }
	}

      if (debug_tui)
	{
	  tui_debug_printf ("after final size calculation");
	  tui_debug_printf ("available_size = %d, used_size = %d",
			    available_size, used_size);
	  tui_debug_printf ("total_weight = %d, last_index = %d",
			    total_weight, last_index);
	  tui_debug_print_size_info (info);
	}
    }

  /* Step 3: Resize.  */
  int size_accum = 0;
  const int maximum = m_vertical ? height : width;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      /* If we fall off the bottom, just make allocations overlap.
	 GIGO.  */
      if (size_accum + info[i].size > maximum)
	size_accum = maximum - info[i].size;
      else if (info[i].share_box)
	--size_accum;
      if (m_vertical)
	m_splits[i].layout->apply (x, y + size_accum, width, info[i].size,
				   preserve_cmd_win_size_p);
      else
	m_splits[i].layout->apply (x + size_accum, y, info[i].size, height,
				   preserve_cmd_win_size_p);
      size_accum += info[i].size;
    }
}

/* See tui-layout.h.  */

void
tui_layout_split::remove_windows (const char *name)
{
  for (int i = 0; i < m_splits.size (); ++i)
    {
      const char *this_name = m_splits[i].layout->get_name ();
      if (this_name == nullptr)
	m_splits[i].layout->remove_windows (name);
      else if (strcmp (this_name, name) == 0
	       || strcmp (this_name, CMD_NAME) == 0
	       || strcmp (this_name, STATUS_NAME) == 0)
	{
	  /* Keep.  */
	}
      else
	{
	  m_splits.erase (m_splits.begin () + i);
	  --i;
	}
    }
}

/* See tui-layout.h.  */

void
tui_layout_split::replace_window (const char *name, const char *new_window)
{
  for (auto &item : m_splits)
    item.layout->replace_window (name, new_window);
}

/* See tui-layout.h.  */

void
tui_layout_split::specification (ui_file *output, int depth)
{
  if (depth > 0)
    gdb_puts ("{", output);

  if (!m_vertical)
    gdb_puts ("-horizontal ", output);

  bool first = true;
  for (auto &item : m_splits)
    {
      if (!first)
	gdb_puts (" ", output);
      first = false;
      item.layout->specification (output, depth + 1);
      gdb_printf (output, " %d", item.weight);
    }

  if (depth > 0)
    gdb_puts ("}", output);
}

/* See tui-layout.h.  */

std::string
tui_layout_split::layout_fingerprint () const
{
  for (auto &item : m_splits)
    {
      std::string fp = item.layout->layout_fingerprint ();
      if (!fp.empty ())
	return std::string (m_vertical ? "V" : "H") + fp;
    }

  return "";
}

/* Destroy the layout associated with SELF.  */

static void
destroy_layout (struct cmd_list_element *self, void *context)
{
  tui_layout_split *layout = (tui_layout_split *) context;
  size_t index = find_layout (layout);
  layouts.erase (layouts.begin () + index);
}

/* List holding the sub-commands of "layout".  */

static struct cmd_list_element *layout_list;

/* Called to implement 'tui layout'.  */

static void
tui_layout_command (const char *args, int from_tty)
{
  help_list (layout_list, "tui layout ", all_commands, gdb_stdout);
}

/* Add a "layout" command with name NAME that switches to LAYOUT.  */

static struct cmd_list_element *
add_layout_command (const char *name, tui_layout_split *layout)
{
  struct cmd_list_element *cmd;

  string_file spec;
  layout->specification (&spec, 0);

  gdb::unique_xmalloc_ptr<char> doc
    = xstrprintf (_("Apply the \"%s\" layout.\n\
This layout was created using:\n\
  tui new-layout %s %s"),
		  name, name, spec.c_str ());

  cmd = add_cmd (name, class_tui, nullptr, doc.get (), &layout_list);
  cmd->set_context (layout);
  /* There is no API to set this.  */
  cmd->func = tui_apply_layout;
  cmd->destroyer = destroy_layout;
  cmd->doc_allocated = 1;
  doc.release ();
  layouts.emplace_back (layout);

  return cmd;
}

/* Initialize the standard layouts.  */

static void
initialize_layouts ()
{
  tui_layout_split *layout;

  layout = new tui_layout_split ();
  layout->add_window (SRC_NAME, 2);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  add_layout_command (SRC_NAME, layout);

  layout = new tui_layout_split ();
  layout->add_window (DISASSEM_NAME, 2);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  add_layout_command (DISASSEM_NAME, layout);

  layout = new tui_layout_split ();
  layout->add_window (SRC_NAME, 1);
  layout->add_window (DISASSEM_NAME, 1);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  add_layout_command ("split", layout);

  layout = new tui_layout_split ();
  layout->add_window (DATA_NAME, 1);
  layout->add_window (SRC_NAME, 1);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  layouts.emplace_back (layout);
  src_regs_layout = layout;

  layout = new tui_layout_split ();
  layout->add_window (DATA_NAME, 1);
  layout->add_window (DISASSEM_NAME, 1);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  layouts.emplace_back (layout);
  asm_regs_layout = layout;
}



/* A helper function that returns true if NAME is the name of an
   available window.  */

static bool
validate_window_name (const std::string &name)
{
  auto iter = known_window_types->find (name);
  return iter != known_window_types->end ();
}

/* Implementation of the "tui new-layout" command.  */

static void
tui_new_layout_command (const char *spec, int from_tty)
{
  std::string new_name = extract_arg (&spec);
  if (new_name.empty ())
    error (_("No layout name specified"));
  if (new_name[0] == '-')
    error (_("Layout name cannot start with '-'"));

  bool is_vertical = true;
  spec = skip_spaces (spec);
  if (check_for_argument (&spec, "-horizontal"))
    is_vertical = false;

  std::vector<std::unique_ptr<tui_layout_split>> splits;
  splits.emplace_back (new tui_layout_split (is_vertical));
  std::unordered_set<std::string> seen_windows;
  while (true)
    {
      spec = skip_spaces (spec);
      if (spec[0] == '\0')
	break;

      if (spec[0] == '{')
	{
	  is_vertical = true;
	  spec = skip_spaces (spec + 1);
	  if (check_for_argument (&spec, "-horizontal"))
	    is_vertical = false;
	  splits.emplace_back (new tui_layout_split (is_vertical));
	  continue;
	}

      bool is_close = false;
      std::string name;
      if (spec[0] == '}')
	{
	  is_close = true;
	  ++spec;
	  if (splits.size () == 1)
	    error (_("Extra '}' in layout specification"));
	}
      else
	{
	  name = extract_arg (&spec);
	  if (name.empty ())
	    break;
	  if (!validate_window_name (name))
	    error (_("Unknown window \"%s\""), name.c_str ());
	  if (seen_windows.find (name) != seen_windows.end ())
	    error (_("Window \"%s\" seen twice in layout"), name.c_str ());
	}

      ULONGEST weight = get_ulongest (&spec, '}');
      if ((int) weight != weight)
	error (_("Weight out of range: %s"), pulongest (weight));
      if (is_close)
	{
	  std::unique_ptr<tui_layout_split> last_split
	    = std::move (splits.back ());
	  splits.pop_back ();
	  splits.back ()->add_split (std::move (last_split), weight);
	}
      else
	{
	  splits.back ()->add_window (name.c_str (), weight);
	  seen_windows.insert (name);
	}
    }
  if (splits.size () > 1)
    error (_("Missing '}' in layout specification"));
  if (seen_windows.empty ())
    error (_("New layout does not contain any windows"));
  if (seen_windows.find (CMD_NAME) == seen_windows.end ())
    error (_("New layout does not contain the \"" CMD_NAME "\" window"));

  gdb::unique_xmalloc_ptr<char> cmd_name
    = make_unique_xstrdup (new_name.c_str ());
  std::unique_ptr<tui_layout_split> new_layout = std::move (splits.back ());
  struct cmd_list_element *cmd
    = add_layout_command (cmd_name.get (), new_layout.get ());
  cmd->name_allocated = 1;
  cmd_name.release ();
  new_layout.release ();
}

/* Function to initialize gdb commands, for tui window layout
   manipulation.  */

void _initialize_tui_layout ();
void
_initialize_tui_layout ()
{
  struct cmd_list_element *layout_cmd
    = add_prefix_cmd ("layout", class_tui, tui_layout_command, _("\
Change the layout of windows.\n\
Usage: tui layout prev | next | LAYOUT-NAME"),
		      &layout_list, 0, tui_get_cmd_list ());
  add_com_alias ("layout", layout_cmd, class_tui, 0);

  add_cmd ("next", class_tui, tui_next_layout_command,
	   _("Apply the next TUI layout."),
	   &layout_list);
  add_cmd ("prev", class_tui, tui_prev_layout_command,
	   _("Apply the previous TUI layout."),
	   &layout_list);
  add_cmd ("regs", class_tui, tui_regs_layout_command,
	   _("Apply the TUI register layout."),
	   &layout_list);

  add_cmd ("new-layout", class_tui, tui_new_layout_command,
	   _("Create a new TUI layout.\n\
Usage: tui new-layout [-horizontal] NAME WINDOW WEIGHT [WINDOW WEIGHT]...\n\
Create a new TUI layout.  The new layout will be named NAME,\n\
and can be accessed using \"layout NAME\".\n\
The windows will be displayed in the specified order.\n\
A WINDOW can also be of the form:\n\
  { [-horizontal] NAME WEIGHT [NAME WEIGHT]... }\n\
This form indicates a sub-frame.\n\
Each WEIGHT is an integer, which holds the relative size\n\
to be allocated to the window."),
	   tui_get_cmd_list ());

  initialize_layouts ();
  initialize_known_windows ();
}
