/* Public Domain Curses */

#include <curspriv.h>

RCSID("$Id: window.c,v 1.62 2008/07/13 16:08:18 wmcbrine Exp $")

/*man-start**************************************************************

  Name:                                                         window

  Synopsis:
        WINDOW *newwin(int nlines, int ncols, int begy, int begx);
        WINDOW *derwin(WINDOW* orig, int nlines, int ncols,
                int begy, int begx);
        WINDOW *subwin(WINDOW* orig, int nlines, int ncols,
                int begy, int begx);
        WINDOW *dupwin(WINDOW *win);
        int delwin(WINDOW *win);
        int mvwin(WINDOW *win, int y, int x);
        int mvderwin(WINDOW *win, int pary, int parx);
        int syncok(WINDOW *win, bool bf);
        void wsyncup(WINDOW *win);
        void wcursyncup(WINDOW *win);
        void wsyncdown(WINDOW *win);

        WINDOW *resize_window(WINDOW *win, int nlines, int ncols);
        int wresize(WINDOW *win, int nlines, int ncols);
        WINDOW *PDC_makelines(WINDOW *win);
        WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx);
        void PDC_sync(WINDOW *win);

  Description:
        newwin() creates a new window with the given number of lines,
        nlines and columns, ncols. The upper left corner of the window
        is at line begy, column begx. If nlines is zero, it defaults to
        LINES - begy; ncols to COLS - begx. Create a new full-screen
        window by calling newwin(0, 0, 0, 0).

        delwin() deletes the named window, freeing all associated
        memory. In the case of overlapping windows, subwindows should be
        deleted before the main window.

        mvwin() moves the window so that the upper left-hand corner is
        at position (y,x). If the move would cause the window to be off
        the screen, it is an error and the window is not moved. Moving
        subwindows is allowed.

        subwin() creates a new subwindow within a window.  The
        dimensions of the subwindow are nlines lines and ncols columns.
        The subwindow is at position (begy, begx) on the screen.  This
        position is relative to the screen, and not to the window orig.
        Changes made to either window will affect both.  When using this
        routine, you will often need to call touchwin() before calling
        wrefresh().

        derwin() is the same as subwin(), except that begy and begx are
        relative to the origin of the window orig rather than the
        screen.  There is no difference between subwindows and derived
        windows.

        mvderwin() moves a derived window (or subwindow) inside its
        parent window.  The screen-relative parameters of the window are
        not changed.  This routine is used to display different parts of
        the parent window at the same physical position on the screen.

        dupwin() creates an exact duplicate of the window win.

        wsyncup() causes a touchwin() of all of the window's parents.

        If wsyncok() is called with a second argument of TRUE, this
        causes a wsyncup() to be called every time the window is
        changed.

        wcursyncup() causes the current cursor position of all of a
        window's ancestors to reflect the current cursor position of the
        current window.

        wsyncdown() causes a touchwin() of the current window if any of
        its parent's windows have been touched.

        resize_window() allows the user to resize an existing window. It
        returns the pointer to the new window, or NULL on failure.

        wresize() is an ncurses-compatible wrapper for resize_window().
        Note that, unlike ncurses, it will NOT process any subwindows of
        the window. (However, you still can call it _on_ subwindows.) It
        returns OK or ERR.

        PDC_makenew() allocates all data for a new WINDOW * except the
        actual lines themselves. If it's unable to allocate memory for
        the window structure, it will free all allocated memory and
        return a NULL pointer.

        PDC_makelines() allocates the memory for the lines.

        PDC_sync() handles wrefresh() and wsyncup() calls when a window
        is changed.

  Return Value:
        newwin(), subwin(), derwin() and dupwin() return a pointer
        to the new window, or NULL on failure. delwin(), mvwin(),
        mvderwin() and syncok() return OK or ERR. wsyncup(),
        wcursyncup() and wsyncdown() return nothing.

  Errors:
        It is an error to call resize_window() before calling initscr().
        Also, an error will be generated if we fail to create a newly
        sized replacement window for curscr, or stdscr. This could
        happen when increasing the window size. NOTE: If this happens,
        the previously successfully allocated windows are left alone;
        i.e., the resize is NOT cancelled for those windows.

  Portability                                X/Open    BSD    SYS V
        newwin                                  Y       Y       Y
        delwin                                  Y       Y       Y
        mvwin                                   Y       Y       Y
        subwin                                  Y       Y       Y
        derwin                                  Y       -       Y
        mvderwin                                Y       -       Y
        dupwin                                  Y       -      4.0
        wsyncup                                 Y       -      4.0
        syncok                                  Y       -      4.0
        wcursyncup                              Y       -      4.0
        wsyncdown                               Y       -      4.0
        resize_window                           -       -       -
        wresize                                 -       -       -
        PDC_makelines                           -       -       -
        PDC_makenew                             -       -       -
        PDC_sync                                -       -       -

**man-end****************************************************************/

#include <stdlib.h>

WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx)
{
    WINDOW *win;

    PDC_LOG(("PDC_makenew() - called: lines %d cols %d begy %d begx %d\n",
             nlines, ncols, begy, begx));

    /* allocate the window structure itself */

    if ((win = calloc(1, sizeof(WINDOW))) == (WINDOW *)NULL)
        return win;

    /* allocate the line pointer array */

    if ((win->_y = malloc(nlines * sizeof(chtype *))) == NULL)
    {
        free(win);
        return (WINDOW *)NULL;
    }

    /* allocate the minchng and maxchng arrays */

    if ((win->_firstch = malloc(nlines * sizeof(int))) == NULL)
    {
        free(win->_y);
        free(win);
        return (WINDOW *)NULL;
    }

    if ((win->_lastch = malloc(nlines * sizeof(int))) == NULL)
    {
        free(win->_firstch);
        free(win->_y);
        free(win);
        return (WINDOW *)NULL;
    }

    /* initialize window variables */

    win->_maxy = nlines;  /* real max screen size */
    win->_maxx = ncols;   /* real max screen size */
    win->_begy = begy;
    win->_begx = begx;
    win->_bkgd = ' ';     /* wrs 4/10/93 -- initialize background to blank */
    win->_clear = (bool) ((nlines == LINES) && (ncols == COLS));
    win->_bmarg = nlines - 1;
    win->_parx = win->_pary = -1;

    /* init to say window all changed */

    touchwin(win);

    return win;
}

WINDOW *PDC_makelines(WINDOW *win)
{
    int i, j, nlines, ncols;

    PDC_LOG(("PDC_makelines() - called: lines %d cols %d\n", nlines, ncols));

    if (!win)
        return (WINDOW *)NULL;

    nlines = win->_maxy;
    ncols = win->_maxx;

    for (i = 0; i < nlines; i++)
    {
        if ((win->_y[i] = malloc(ncols * sizeof(chtype))) == NULL)
        {
            /* if error, free all the data */

            for (j = 0; j < i; j++)
                free(win->_y[j]);

            free(win->_firstch);
            free(win->_lastch);
            free(win->_y);
            free(win);

            return (WINDOW *)NULL;
        }
    }

    return win;
}

void PDC_sync(WINDOW *win)
{
    PDC_LOG(("PDC_sync() - called:\n"));

    if (win->_immed)
        wrefresh(win);
    if (win->_sync)
        wsyncup(win);
}

WINDOW *newwin(int nlines, int ncols, int begy, int begx)
{
    WINDOW *win;

    PDC_LOG(("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n",
             nlines, ncols, begy, begx));

    if (!nlines)
        nlines = LINES - begy;
    if (!ncols)
        ncols  = COLS  - begx;

    if ( (begy + nlines > SP->lines || begx + ncols > SP->cols)
        || !(win = PDC_makenew(nlines, ncols, begy, begx))
        || !(win = PDC_makelines(win)) )
        return (WINDOW *)NULL;

    werase(win);

    return win;
}

int delwin(WINDOW *win)
{
    int i;

    PDC_LOG(("delwin() - called\n"));

    if (!win)
        return ERR;

    /* subwindows use parents' lines */

    if (!(win->_flags & (_SUBWIN|_SUBPAD)))
        for (i = 0; i < win->_maxy && win->_y[i]; i++)
            if (win->_y[i])
                free(win->_y[i]);

    free(win->_firstch);
    free(win->_lastch);
    free(win->_y);
    free(win);

    return OK;
}

int mvwin(WINDOW *win, int y, int x)
{
    PDC_LOG(("mvwin() - called\n"));

    if (!win || (y + win->_maxy > LINES || y < 0)
             || (x + win->_maxx > COLS || x < 0))
        return ERR;

    win->_begy = y;
    win->_begx = x;
    touchwin(win);

    return OK;
}

WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
{
    WINDOW *win;
    int i, j, k;

    PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n",
             nlines, ncols, begy, begx));

    /* make sure window fits inside the original one */

    if (!orig || (begy < orig->_begy) || (begx < orig->_begx) ||
        (begy + nlines) > (orig->_begy + orig->_maxy) ||
        (begx + ncols) > (orig->_begx + orig->_maxx))
        return (WINDOW *)NULL;

    j = begy - orig->_begy;
    k = begx - orig->_begx;

    if (!nlines)
        nlines = orig->_maxy - 1 - j;
    if (!ncols)
        ncols  = orig->_maxx - 1 - k;

    if ( !(win = PDC_makenew(nlines, ncols, begy, begx)) )
        return (WINDOW *)NULL;

    /* initialize window variables */

    win->_attrs = orig->_attrs;
    win->_bkgd = orig->_bkgd;
    win->_leaveit = orig->_leaveit;
    win->_scroll = orig->_scroll;
    win->_nodelay = orig->_nodelay;
    win->_use_keypad = orig->_use_keypad;
    win->_immed = orig->_immed;
    win->_sync = orig->_sync;
    win->_pary = j;
    win->_parx = k;
    win->_parent = orig;

    for (i = 0; i < nlines; i++, j++)
        win->_y[i] = orig->_y[j] + k;

    win->_flags |= _SUBWIN;

    return win;
}

WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
{
    return subwin(orig, nlines, ncols, begy + orig->_begy, begx + orig->_begx);
}

int mvderwin(WINDOW *win, int pary, int parx)
{
    int i, j;
    WINDOW *mypar;

    if (!win || !(win->_parent))
        return ERR;

    mypar = win->_parent;

    if (pary < 0 || parx < 0 || (pary + win->_maxy) > mypar->_maxy ||
                                (parx + win->_maxx) > mypar->_maxx)
        return ERR;

    j = pary;

    for (i = 0; i < win->_maxy; i++)
        win->_y[i] = (mypar->_y[j++]) + parx;

    win->_pary = pary;
    win->_parx = parx;

    return OK;
}

WINDOW *dupwin(WINDOW *win)
{
    WINDOW *new;
    chtype *ptr, *ptr1;
    int nlines, ncols, begy, begx, i;

    if (!win)
        return (WINDOW *)NULL;

    nlines = win->_maxy;
    ncols = win->_maxx;
    begy = win->_begy;
    begx = win->_begx;

    if ( !(new = PDC_makenew(nlines, ncols, begy, begx))
        || !(new = PDC_makelines(new)) )
        return (WINDOW *)NULL;

    /* copy the contents of win into new */

    for (i = 0; i < nlines; i++)
    {
        for (ptr = new->_y[i], ptr1 = win->_y[i];
             ptr < new->_y[i] + ncols; ptr++, ptr1++)
            *ptr = *ptr1;

        new->_firstch[i] = 0;
        new->_lastch[i] = ncols - 1;
    }

    new->_curx = win->_curx;
    new->_cury = win->_cury;
    new->_maxy = win->_maxy;
    new->_maxx = win->_maxx;
    new->_begy = win->_begy;
    new->_begx = win->_begx;
    new->_flags = win->_flags;
    new->_attrs = win->_attrs;
    new->_clear = win->_clear;
    new->_leaveit = win->_leaveit;
    new->_scroll = win->_scroll;
    new->_nodelay = win->_nodelay;
    new->_use_keypad = win->_use_keypad;
    new->_tmarg = win->_tmarg;
    new->_bmarg = win->_bmarg;
    new->_parx = win->_parx;
    new->_pary = win->_pary;
    new->_parent = win->_parent;
    new->_bkgd = win->_bkgd;
    new->_flags = win->_flags;

    return new;
}

WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
{
    WINDOW *new;
    int i, save_cury, save_curx, new_begy, new_begx;

    PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
             nlines, ncols));

    if (!win)
        return (WINDOW *)NULL;

    if (win->_flags & _SUBPAD)
    {
        if ( !(new = subpad(win->_parent, nlines, ncols,
                            win->_begy, win->_begx)) )
            return (WINDOW *)NULL;
    }
    else if (win->_flags & _SUBWIN)
    {
        if ( !(new = subwin(win->_parent, nlines, ncols,
                            win->_begy, win->_begx)) )
            return (WINDOW *)NULL;
    }
    else
    {
        if (win == SP->slk_winptr)
        {
            new_begy = SP->lines - SP->slklines;
            new_begx = 0;
        }
        else
        {
            new_begy = win->_begy;
            new_begx = win->_begx;
        }

        if ( !(new = PDC_makenew(nlines, ncols, new_begy, new_begx)) )
            return (WINDOW *)NULL;
    }

    save_curx = min(win->_curx, new->_maxx);
    save_cury = min(win->_cury, new->_maxy);

    if (!(win->_flags & (_SUBPAD|_SUBWIN)))
    {
        if ( !(new = PDC_makelines(new)) )
            return (WINDOW *)NULL;

        werase(new);

        copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1,
                min(win->_maxx, new->_maxx) - 1, FALSE);

        for (i = 0; i < win->_maxy && win->_y[i]; i++)
            if (win->_y[i])
                free(win->_y[i]);
    }

    new->_flags = win->_flags;
    new->_attrs = win->_attrs;
    new->_clear = win->_clear;
    new->_leaveit = win->_leaveit;
    new->_scroll = win->_scroll;
    new->_nodelay = win->_nodelay;
    new->_use_keypad = win->_use_keypad;
    new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg;
    new->_bmarg = (win->_bmarg == win->_maxy - 1) ?
                  new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1));
    new->_parent = win->_parent;
    new->_immed = win->_immed;
    new->_sync = win->_sync;
    new->_bkgd = win->_bkgd;

    new->_curx = save_curx;
    new->_cury = save_cury;

    free(win->_firstch);
    free(win->_lastch);
    free(win->_y);

    *win = *new;
    free(new);

    return win;
}

int wresize(WINDOW *win, int nlines, int ncols)
{
    return (resize_window(win, nlines, ncols) ? OK : ERR);
}

void wsyncup(WINDOW *win)
{
    WINDOW *tmp;

    PDC_LOG(("wsyncup() - called\n"));

    for (tmp = win; tmp; tmp = tmp->_parent)
        touchwin(tmp);
}

int syncok(WINDOW *win, bool bf)
{
    PDC_LOG(("syncok() - called\n"));

    if (!win)
        return ERR;

    win->_sync = bf;

    return OK;
}

void wcursyncup(WINDOW *win)
{
    WINDOW *tmp;

    PDC_LOG(("wcursyncup() - called\n"));

    for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent)
        wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx);
}

void wsyncdown(WINDOW *win)
{
    WINDOW *tmp;

    PDC_LOG(("wsyncdown() - called\n"));

    for (tmp = win; tmp; tmp = tmp->_parent)
    {
        if (is_wintouched(tmp))
        {
            touchwin(win);
            break;
        }
    }
}
