/*
 * freescope - Free source browser
 * Copyright (C) 2001  Olivier Deme
 * 
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

// FILE: wndhelp.cpp

/************/
/* INCLUDES */
/************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

#include "wndhelp.h"


/***************/
/* DEFINITIONS */
/***************/

#define ctrl(x) (x & 037)


/************************/
/* FUNCTION DEFINITIONS */
/************************/

/*
 * FUNCTION:    WndHelp::WndHelp
 *
 * DESCRIPTION: Constructors. Set-up a new help window.
 *
 * IN:
 * IN-OUT:
 * RETURN CODE:
 */

WndHelp::WndHelp () :
                m_start_line(0),
                m_start_pos(0)
{
    m_text = 
    "COMMAND LIST (default keys)\n"
    "***************************\n"
    "\n"
    "QUERY MODE\n"
    "----------\n"
    "\n"
    "UP ARROW       Go to previous category\n"
    "DOWN ARROW     Go to next category\n"
    "TAB            Go to next category\n"
    "CTRL-N         Next symbol completion\n"
    "CTRL-P         Previous symbol completion\n"
    "CTRL-B         Previous query\n"
    "CTRL-F         Next query\n"
    "CTR-D          Quit freescope\n"
    "CTRL-W         Switch to NAVIGATION mode\n"
    "\n"
    "\n"
    "NAVIGATION MODE\n" 
    "---------------\n"
    "\n"
    "J / DOWN       Select next result\n"
    "K / UP         Select previous result\n"
    "H / LEFT       Show previous page results\n"
    "L / RIGHT      Show next page results\n"
    "ENTER/SPACE    Start editor on selected result\n"
    "?              Show this help\n"
    "LEFT ARROW     Show previous results\n"
    "RIGHT ARROW    Show next results\n"
    "CTR-D          Quit freescope\n"
    "CTRL-W / TAB   Switch to QUERY mode\n"
    "\n\n"
    "CHANGING MODE\n"
    "-------------\n"
    "\n"
    "S              Select highlighted match\n"
    "CTRL-A         Select all matches\n"
    "CTRL-D         Apply changes\n"
    "\n\n"
    "HELP MODE\n"
    "---------\n"
    "\n"
    "J / DOWN       Scroll down one line\n"
    "K / UP         Scroll up one line\n";
    
    m_window     = newwin(0, 0, 0, 0);
    m_panel = new_panel(m_window);

    keypad(m_window, TRUE);

    cbreak();
    noecho();
    nonl();

    mvwprintw(m_window, 0, 0, (char*)m_text.c_str());

    top_panel(m_panel);
    update_panels();
    doupdate();

#ifndef HAVE_LIBNCURSES
    noecho();
#endif // HAVE_LIBNCURSES

    // Processing loop
    for (;;)
    {
        int key;

        key = wgetch(m_window);

        if (do_key(key) == true)
            break;
    }
}

/*
 * FUNCTION:    WndHelp::~WndHelp
 *
 * DESCRIPTION: Destructor
 *
 * IN:
 * IN-OUT:
 * RETURN CODE:
 */

WndHelp::~WndHelp ()
{
    bottom_panel(m_panel);
    update_panels();
    doupdate();
    delwin(panel_window(m_panel));
}

/*
 * FUNCTION:    do_key
 *
 * DESCRIPTION: This function processes one key stroke
 *
 * IN;          key     The key pressed
 * IN-OUT:
 * OUT:
 * RETURN CODE: true if key means "exit help". false otherwise.
 * SIDE EFFECT:
 */

bool WndHelp::do_key (int key)
{
    bool ret;

    switch (key)
    {
    case 'j':
    case KEY_DOWN:      scroll_down();
                        ret = false;
                        break;
    case 'k':
    case KEY_UP:        scroll_up();
                        ret = false;
                        break;
    default:            ret = true;
                        break;
    }

    top_panel(m_panel);
    update_panels();
    doupdate();

    return ret;
}

/*
 * FUNCTION:    WndHelp::scroll_down
 *
 * DESCRIPTION: This function scrolls down the help by one line if needed.
 *
 * IN:
 * IN-OUT:
 * OUT:
 * RETURN CODE:
 * SIDE EFFECT:
 */

void WndHelp::scroll_down ()
{
    string            display_string;
    int               width;
    int               height;
    int               lines = 1;
    string::size_type pos   = 0;

    getmaxyx(stdscr, height, width);

    // Get number of lines in help text
    while ((pos = m_text.find('\n', pos)) != string::npos)
    {
        pos += 1;
        ++lines;
    }
    
    if (lines - m_start_line <= height)
        return;
    
    werase(m_window);
    
    // Scroll one line
    m_start_pos = m_text.find('\n', m_start_pos) + 1;
    display_string = m_text.substr(m_start_pos);
    mvwprintw(m_window, 0, 0, (char*)display_string.c_str());
    ++m_start_line;
}

/*
 * FUNCTION:    WndHelp::scroll_up
 *
 * DESCRIPTION: This function scrolls up the help by one line if needed.
 *
 * IN:
 * IN-OUT:
 * OUT:
 * RETURN CODE:
 * SIDE EFFECT:
 */

void WndHelp::scroll_up ()
{
    string            display_string;
    int               width;
    int               height;
    int               lines = 1;
    string::size_type pos   = 0;

    if (m_start_pos == 0)
        return;

    getmaxyx(stdscr, height, width);

    // Get number of lines in help text
    while ((pos = m_text.find('\n', pos)) != string::npos)
    {
        pos += 1;
        ++lines;
    }
    
    // if (lines - m_start_line < height)
      //   return;
    
    werase(m_window);
    
    // Scroll one line
    m_start_pos = m_text.rfind('\n', m_start_pos - 2) + 1;
    display_string = m_text.substr(m_start_pos);
    mvwprintw(m_window, 0, 0, (char*)display_string.c_str());
    --m_start_line;
}


syntax highlighted by Code2HTML, v. 0.9.1