/* TUI data manipulation routines.

   Copyright (C) 1998-2021 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-win.h"
#include "tui/tui-wingeneral.h"
#include "tui/tui-winsource.h"
#include "gdb_curses.h"
#include <algorithm>

struct tui_win_info *tui_win_list[MAX_MAJOR_WINDOWS];

static int term_height, term_width;
static struct tui_win_info *win_with_focus = NULL;

static bool win_resized = false;

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


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


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


/* Set the logical focus to win_info.  */
void
tui_set_win_focus_to (struct tui_win_info *win_info)
{
  if (win_info != NULL)
    {
      tui_unhighlight_win (win_with_focus);
      win_with_focus = win_info;
      tui_highlight_win (win_info);
    }
}


/* 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;
}


/* 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)
{
  auto iter = std::find (tui_windows.begin (), tui_windows.end (), cur_win);
  gdb_assert (iter != tui_windows.end ());

  gdb_assert (cur_win->can_focus ());
  /* This won't loop forever since we can't have just an un-focusable
     window.  */
  while (true)
    {
      ++iter;
      if (iter == tui_windows.end ())
	iter = tui_windows.begin ();
      if ((*iter)->can_focus ())
	break;
    }

  return *iter;
}


/* 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)
{
  auto iter = std::find (tui_windows.rbegin (), tui_windows.rend (), cur_win);
  gdb_assert (iter != tui_windows.rend ());

  gdb_assert (cur_win->can_focus ());
  /* This won't loop forever since we can't have just an un-focusable
     window.  */
  while (true)
    {
      ++iter;
      if (iter == tui_windows.rend ())
	iter = tui_windows.rbegin ();
      if ((*iter)->can_focus ())
	break;
    }

  return *iter;
}


void
tui_win_info::rerender ()
{
  check_and_display_highlight_if_needed ();
}
