/*
 * dselect - Debian package maintenance user interface
 * baselist.cc - list of somethings
 *
 * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk>
 * Copyright © 2001 Wichert Akkerman <wakkerma@debian.org>
 *
 * This 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 2 of the License, or
 * (at your option) any later version.
 *
 * This 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 <config.h>
#include <compat.h>

#include <sys/ioctl.h>
#include <sys/termios.h>

#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>

#include "dselect.h"
#include "bindings.h"

void mywerase(WINDOW *win) {
  int my,mx,y,x;
  getmaxyx(win,my,mx);
  for (y=0; y<my; y++) {
    wmove(win,y,0); for (x=0; x<mx; x++) waddch(win,' ');
  }
  wmove(win,0,0);
}

baselist *baselist::signallist= 0;
void baselist::sigwinchhandler(int) {
  struct winsize size;
  debug(dbg_general, "baselist::sigwinchhandler(), signallist=%p", signallist);
  baselist *p= signallist;
  p->enddisplay();
  endwin(); initscr();
  if (ioctl(fileno(stdout), TIOCGWINSZ, &size) != 0) ohshite(_("ioctl(TIOCGWINSZ) failed"));
  resizeterm(size.ws_row, size.ws_col); wrefresh(curscr);
  p->startdisplay();
  if (doupdate() == ERR) ohshite(_("doupdate in SIGWINCH handler failed"));
}

static void cu_sigwinch(int, void **argv) {
  struct sigaction *osigactp= (struct sigaction*)argv[0];
  sigset_t *oblockedp= (sigset_t*)argv[1];

  if (sigaction(SIGWINCH,osigactp,0)) ohshite(_("failed to restore old SIGWINCH sigact"));
  delete osigactp;
  if (sigprocmask(SIG_SETMASK,oblockedp,0)) ohshite(_("failed to restore old signal mask"));
  delete oblockedp;
}

void baselist::setupsigwinch() {
  sigemptyset(&sigwinchset);
  sigaddset(&sigwinchset,SIGWINCH);

  osigactp= new(struct sigaction);
  oblockedp= new(sigset_t);
  if (sigprocmask(0,0,oblockedp)) ohshite(_("failed to get old signal mask"));
  if (sigaction(SIGWINCH,0,osigactp)) ohshite(_("failed to get old SIGWINCH sigact"));

  push_cleanup(cu_sigwinch,~0, 0,0, 2,(void*)osigactp,(void*)oblockedp);

  if (sigprocmask(SIG_BLOCK,&sigwinchset,0)) ohshite(_("failed to block SIGWINCH"));
  memset(&nsigact,0,sizeof(nsigact));
  nsigact.sa_handler= sigwinchhandler;
  sigemptyset(&nsigact.sa_mask);
//nsigact.sa_flags= SA_INTERRUPT;
  if (sigaction(SIGWINCH,&nsigact,0)) ohshite(_("failed to set new SIGWINCH sigact"));
}

void baselist::setheights() {
  int y= ymax - (title_height + colheads_height + thisstate_height);
  assert(y>=1);
  if (showinfo==2 && y>=7) {
    list_height= 5;
    whatinfo_height= 1;
    info_height= y-6;
  } else if (showinfo==1 && y>=10) {
    list_height= y/2;
    info_height= (y-1)/2;
    whatinfo_height= 1;
  } else {
    list_height= y;
    info_height= 0;
    whatinfo_height= 0;
  }
  colheads_row= title_height;
  list_row= colheads_row + colheads_height;
  thisstate_row= list_row + list_height;
  info_row= thisstate_row + thisstate_height;
  whatinfo_row= ymax - 1;
}

void baselist::startdisplay() {
  debug(dbg_general, "baselist[%p]::startdisplay()", this);
  cbreak(); noecho(); nonl(); keypad(stdscr,TRUE);
  clear(); wnoutrefresh(stdscr);

  // find attributes
  if (has_colors() && start_color()==OK && COLOR_PAIRS >= numscreenparts) {
    int i;
    printf("allocing\n");
    for (i = 1; i < numscreenparts; i++) {
       if (init_pair(i, color[i].fore, color[i].back) != OK)
         ohshite(_("failed to allocate colour pair"));
    }
    /* TODO: should use an array of attr's, indexed by attr name. Oh well. */
    list_attr=		COLOR_PAIR(list)	| color[list].attr;
    listsel_attr= 	COLOR_PAIR(listsel)	| color[listsel].attr;
    title_attr=		COLOR_PAIR(title)	| color[title].attr;
    thisstate_attr=	COLOR_PAIR(thisstate)	| color[thisstate].attr;
    selstate_attr=	COLOR_PAIR(selstate)	| color[selstate].attr;
    selstatesel_attr= 	COLOR_PAIR(selstatesel)	| color[selstatesel].attr;
    colheads_attr=	COLOR_PAIR(colheads)	| color[colheads].attr;
    query_attr=		COLOR_PAIR(query)	| color[query].attr;
    info_attr=		COLOR_PAIR(info)	| color[info].attr;
    info_headattr=	COLOR_PAIR(info_head)	| color[info_head].attr;
    whatinfo_attr=	COLOR_PAIR(whatinfo)	| color[whatinfo].attr;
    helpscreen_attr=	COLOR_PAIR(helpscreen)	| color[helpscreen].attr;
  } else {
    /* User defined attributes for B&W mode are not currently supported. */
    title_attr= A_REVERSE;
    thisstate_attr= A_STANDOUT;
    list_attr= 0;
    listsel_attr= A_STANDOUT;
    selstate_attr= A_BOLD;
    selstatesel_attr= A_STANDOUT;
    colheads_attr= A_BOLD;
    query_attr= title_attr;
    info_attr= list_attr;
    info_headattr= A_BOLD;
    whatinfo_attr= thisstate_attr;
    helpscreen_attr= A_NORMAL;
  }

  // set up windows and pads, based on screen size
  getmaxyx(stdscr,ymax,xmax);
  title_height= ymax>=6;
  colheads_height= ymax>=5;
  thisstate_height= ymax>=3;

  setheights();
  setwidths();

  titlewin= newwin(1,xmax, 0,0);
  if (!titlewin) ohshite(_("failed to create title window"));
  wattrset(titlewin,title_attr);

  whatinfowin= newwin(1,xmax, whatinfo_row,0);
  if (!whatinfowin) ohshite(_("failed to create whatinfo window"));
  wattrset(whatinfowin,whatinfo_attr);

  listpad = newpad(ymax, total_width);
  if (!listpad) ohshite(_("failed to create baselist pad"));

  colheadspad= newpad(1, total_width);
  if (!colheadspad) ohshite(_("failed to create heading pad"));
  wattrset(colheadspad,colheads_attr);

  thisstatepad= newpad(1, total_width);
  if (!thisstatepad) ohshite(_("failed to create thisstate pad"));
  wattrset(thisstatepad,thisstate_attr);

  infopad= newpad(MAX_DISPLAY_INFO, total_width);
  if (!infopad) ohshite(_("failed to create info pad"));
  wattrset(infopad,info_attr);
  wbkgdset(infopad, ' ' | info_attr);

  querywin= newwin(1,xmax,ymax-1,0);
  if (!querywin) ohshite(_("failed to create query window"));
  wbkgdset(querywin, ' ' | query_attr);

  if (cursorline >= topofscreen + list_height) topofscreen= cursorline;
  if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
  if (topofscreen < 0) topofscreen= 0;

  infotopofscreen= 0; leftofscreen= 0;

  redrawall();

  debug(dbg_general,
        "baselist::startdisplay() done ...\n\n"
        " xmax=%d, ymax=%d;\n\n"
        " title_height=%d, colheads_height=%d, list_height=%d;\n"
        " thisstate_height=%d, info_height=%d, whatinfo_height=%d;\n\n"
        " colheads_row=%d, thisstate_row=%d, info_row=%d;\n"
        " whatinfo_row=%d, list_row=%d;\n\n",
        xmax, ymax, title_height, colheads_height, list_height,
        thisstate_height, info_height, whatinfo_height,
        colheads_row, thisstate_row, info_row, whatinfo_row, list_row);
}

void baselist::enddisplay() {
  delwin(titlewin);
  delwin(whatinfowin);
  delwin(listpad);
  delwin(colheadspad);
  delwin(thisstatepad);
  delwin(infopad);
  wmove(stdscr,ymax,0); wclrtoeol(stdscr);
  listpad= 0;
}

void baselist::redrawall() {
  redrawtitle();
  redrawcolheads();
  wattrset(listpad,list_attr); mywerase(listpad);
  ldrawnstart= ldrawnend= -1; // start is first drawn; end is first undrawn; -1=none
  refreshlist();
  redrawthisstate();
  redrawinfo();
}

void baselist::redraw1item(int index) {
  redraw1itemsel(index, index == cursorline);
}

baselist::baselist(keybindings *kb) {
  debug(dbg_general, "baselist[%p]::baselist()", this);

  bindings= kb;
  nitems= 0;

  xmax= -1;
  list_height=0; info_height=0;
  topofscreen= 0; leftofscreen= 0;
  listpad= 0; cursorline= -1;
  showinfo= 1;

  searchstring[0]= 0;
}

void baselist::itd_keys() {
  whatinfovb(_("Keybindings"));

  const int givek= xmax/3;
  bindings->describestart();
  const char **ta;
  while ((ta= bindings->describenext()) != 0) {
    const char **tap= ta+1;
    for (;;) {
      waddstr(infopad, gettext(*tap));
      tap++;  if (!*tap) break;
      waddstr(infopad, ", ");
    }
    int y,x;
    getyx(infopad,y,x);
    if (x >= givek) y++;
    mvwaddstr(infopad, y,givek, ta[0]);
    waddch(infopad,'\n');
  }
}

void baselist::dosearch() {
  int offset, index;
  debug(dbg_general, "baselist[%p]::dosearch(); searchstring='%s'",
        this, searchstring);
  for (offset = 1, index = max(topofscreen, cursorline + 1);
       offset<nitems;
       offset++, index++) {
    if (index >= nitems) index -= nitems;
    if (matchsearch(index)) {
      topofscreen= index-1;
      if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
      if (topofscreen < 0) topofscreen= 0;
      setcursor(index);
      return;
    }
  }
  beep();
}

void baselist::refreshinfo() {
  pnoutrefresh(infopad, infotopofscreen,leftofscreen, info_row,0,
               min(info_row + info_height - 1, info_row + MAX_DISPLAY_INFO - 1),
               min(total_width - leftofscreen - 1, xmax - 1));

  if (whatinfo_height) {
    mywerase(whatinfowin);
    mvwaddstr(whatinfowin,0,0, whatinfovb.string());
    if (infolines > info_height) {
      wprintw(whatinfowin,_("  -- %d%%, press "),
              (int)((infotopofscreen + info_height) * 100.0 / infolines));
      if (infotopofscreen + info_height < infolines) {
        wprintw(whatinfowin,_("%s for more"), bindings->find("iscrollon"));
        if (infotopofscreen) waddstr(whatinfowin, ", ");
      }
      if (infotopofscreen)
        wprintw(whatinfowin, _("%s to go back"),bindings->find("iscrollback"));
      waddch(whatinfowin,'.');
    }
    wnoutrefresh(whatinfowin);
  }
}

void baselist::wordwrapinfo(int offset, const char *m) {
  int usemax= xmax-5;
  debug(dbg_general, "baselist[%p]::wordwrapinfo(%d, '%s')", this, offset, m);
  int wrapping=0;
  for (;;) {
    int offleft=offset; while (*m == ' ' && offleft>0) { m++; offleft--; }
    const char *p= strchr(m,'\n');
    int l= p ? (int)(p-m) : strlen(m);
    while (l && isspace(m[l-1])) l--;
    if (!l || (*m == '.' && l == 1)) {
      if (wrapping) waddch(infopad,'\n');
      waddch(infopad,'\n');
      wrapping= 0;
    } else if (*m == ' ' || usemax < 10) {
      if (wrapping) waddch(infopad,'\n');
      waddnstr(infopad, m, l);
      waddch(infopad,'\n'); wrapping= 0;
    } else {
      int x, y DPKG_ATTR_UNUSED;

      if (wrapping) {
        getyx(infopad, y,x);
        if (x+1 >= usemax) {
          waddch(infopad,'\n');
        } else {
          waddch(infopad,' ');
        }
      }
      for (;;) {
        getyx(infopad, y,x);
        int dosend= usemax-x;
        if (l <= dosend) {
          dosend=l;
        } else {
          int i=dosend;
          while (i > 0 && m[i] != ' ') i--;
          if (i > 0 || x > 0) dosend=i;
        }
        if (dosend) waddnstr(infopad, m, dosend);
        while (dosend < l && m[dosend] == ' ') dosend++;
        l-= dosend; m+= dosend;
        if (l <= 0) break;
        waddch(infopad,'\n');
      }
      wrapping= 1;
    }
    if (!p) break;
    if (getcury(infopad) == (MAX_DISPLAY_INFO - 1)) {
      waddstr(infopad,
              "[The package description is too long and has been truncated...]");
      break;
    }
    m= ++p;
  }
  debug(dbg_general, "baselist[%p]::wordwrapinfo() done", this);
}

baselist::~baselist() { }

/* vi: sw=2 ts=8
 */
