/*
 * This file is part of the apvlv package
 *
 * Copyright (C) 2008 Alf.
 *
 * Contact: Alf <naihe2010@126.com>
 *
 * 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.0 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
/* @CPPFILE ApvlvView.h
 *
 *  Author: Alf <naihe2010@126.com>
 */
/* @date Created: 2008/09/30 00:00:00 Alf */

#ifndef _APVLV_VIEW_H_
#define _APVLV_VIEW_H_

#include "ApvlvMenu.h"
#include "ApvlvDoc.h"
#include "ApvlvWindow.h"
#include "ApvlvCompletion.h"

#include <gtk/gtk.h>

#include <iostream>
#include <list>

namespace apvlv
{
  typedef enum
  {
    SEARCH = '/',
    BACKSEARCH = '?',
    COMMANDMODE = ':'
  } cmd_mode_type;

  class ApvlvDoc;
  class ApvlvWindow;

  class ApvlvView
  {
  public:
    ApvlvView (const char *);

    ~ApvlvView ();

    void show ();

    GtkWidget *widget ();

    ApvlvWindow *currentWindow ();

    void delcurrentWindow ();

    bool newtab (const char *filename);

    bool newtab (ApvlvCore * core);

    void promptcommand (char ch);

    void promptcommand (const char *str);

    void errormessage (const char *str, ...);

    void infomessage (const char *str, ...);

    bool run (const char *str);

    bool loadfile (string file);

    bool loadfile (const char *filename);

    bool loaddir (const char *path);

#ifdef APVLV_WITH_HTML
    bool loadhtml (const char *path);
#endif

    ApvlvCore *hasloaded (const char *filename, int type);

    void regloaded (ApvlvCore *);

    void open ();

    void opendir ();

    void close ();

    void quit ();

    void fullscreen ();

    returnType process (int hastimes, int times, guint keyval);

    returnType subprocess (int times, guint keyval);

    void cmd_show (int ct);

    void cmd_hide ();

    void cmd_auto (const char *);

    void settitle (const char *);

    ApvlvCore *crtadoc ();

  private:
    void refresh ();

    bool destroy;

    ApvlvCompletion *filecompleteinit (const char *s);

    bool runcmd (const char *cmd);

    int new_tabcontext (ApvlvCore * core, bool insertAfterCurr);

    void delete_tabcontext (int tabPos);

    void switch_tabcontext (int tabPos);

    // Caclulate number of pixels that the document should be.
    //  This figure accounts for decorations like (mCmdBar and mHaveTabs).
    // Returns a nonnegative number.
    int adjheight ();

    void switchtab (int tabPos);

    // Update the tab's context and update tab label.
    void windowadded ();

    void updatetabname ();

    int mCmdType;

    guint mProCmd;

    GtkWidget *mMainWindow;

    ApvlvMenu *mMenu;

    GtkWidget *mViewBox;

    GtkWidget *mTabContainer;
    GtkWidget *mCommandBar;

    struct TabEntry
    {
      ApvlvWindow *root;
      ApvlvWindow *curr;

      int numwindows;
      TabEntry (ApvlvWindow * _r, ApvlvWindow * _c, int _n):root (_r),
	curr (_c), numwindows (_n)
      {
      }
    };
    // possibly use GArray instead
    std::vector < TabEntry > mTabList;
    int mCurrTabPos;

    gboolean mHasFull;
    int mWidth, mHeight;

    static void apvlv_view_delete_cb (GtkWidget * wid, GtkAllocation * al,
				      ApvlvView * view);
    static void apvlv_view_resized_cb (GtkWidget * wid, GtkAllocation * al,
				       ApvlvView * view);
    static gint apvlv_view_keypress_cb (GtkWidget * wid, GdkEvent * ev,
					ApvlvView * view);

    static gint apvlv_view_commandbar_cb (GtkWidget * wid, GdkEvent * ev,
					  ApvlvView * view);

    static void apvlv_notebook_switch_cb (GtkWidget * wid,
					  GtkNotebook * notebook, guint num,
					  ApvlvView * view);

    ApvlvWindow *mRootWindow;

    std::vector < ApvlvCore * >mDocs;

    std::vector < string > mCmdHistroy;
    int mCurrHistroy;
    bool mInHistroy;

    static const int APVLV_MENU_HEIGHT, APVLV_CMD_BAR_HEIGHT,
      APVLV_TABS_HEIGHT;
  };

  extern ApvlvView *gView;
}

#endif

/* Local Variables: */
/* mode: c++ */
/* End: */
