/*
 * ===========================
 * VDK Visual Development Kit
 * Version 2.0.0
 * February 2001
 * ===========================
 *
 * Copyright (C) 1998,199,2000,2001 Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#ifndef  _vdkeditor_h
#define  _vdkeditor_h
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <vdk/vdk.h>
#include <vdk/gtksourceview.h>
#include <vdk/rawpixbuf.h>
#define INSERT_MARK "insert"

typedef VDKValueList<VDKString> TokenList;
typedef VDKValueListIterator<VDKString> TokenListIterator;
/*
    Syntax editor class
*/
/*!
  \class VDKEditor
  \brief Provides a nice source editor wrapping Mike Hammerson GtkSourceView.
  Editor provides:
  - syntax higlighting
  - undo capability
  - parenthesis matching
  - word completion
*/
class VDKEditor : public VDKObject
{
  // signal section
 private:
  virtual void LocalConnect();
  static int TabHandler (GtkWidget *widget,
			 GdkEvent *ev,
			 gpointer gp);
  static void HandleRealize(GtkWidget*, gpointer);
 protected:
  TokenList* tokenlist;
  GtkSourceBuffer* buffer;
  GtkWidget* view;
  bool MakeCompletion(const char* word);

  void ShowTipWindow(char* word);
  void AddToken();
  int ShowParenMatch(int start,char keyval,
				GtkWidget* widget,
				bool insert, int restore);
  static int OnKeyRelease (GtkWidget *widget,
                    GdkEvent *ev,
                    gpointer gp); 
  static void OnBufferChanged(GtkWidget* buf, gpointer gp);
  public:
  /*!
    Constructor
    \param owner
    \param buffer NULL widget will make his own buffer, otherwise
    will share <buffer>
    \param left_border if greater than 0 a left window will be made
    with <left_border> size
    \par tip
    left_border should be greater than zero if user wants activate
    ShowLineNumbers property.
   */
  VDKEditor(VDKForm* owner, GtkSourceBuffer* buff = NULL);
  /*!
    Destructor
   */
  virtual ~VDKEditor();
  /*!
  Loads tokens list for word completions from file, 
  returns a newly constructed list to be assigned to editor with SetTokens().
  User is responsible to delete token list when no longer in use.
  File format : simply a token per line.
  \param filename
  */
  static TokenList* LoadTokens( const char* filename);
  /*!
  Sets/gets a tokens list to editor
  \param tkl a valid token list address, if tkl == NULL
  return editor token list address
  */
  TokenList* SetTokens(TokenList* tkl = NULL)
  { 
    if(tkl) 
      tokenlist = tkl; 
    return tokenlist; 
  }

  virtual void SetForeground(VDKRgb rgb, 
			     GtkStateType state = GTK_STATE_NORMAL);

  virtual void SetBackground(VDKRgb color, 
			     GtkStateType state = GTK_STATE_NORMAL);

  virtual void SetFont(VDKFont* font);

  /*!
  Gets text buffer.
  */
  GtkSourceBuffer* Buffer(void) { return buffer; }
  /*!
  Scrolls to a pointer pos or (default) to current
  pointer position, leaving <margin> pixels free
  */
  void Scroll (int pointer = -1, int margin = 0);
  /*!
  Scrolls to a line,column leaving <margin> pixels free
  */
  void Scroll(int line, int col, int margin = 0);
  /*!
  Gets a word 
  \param pos, position into text buffer, if pos == -1 gets the
  word at insertion point.
  */
  char* GetWord(int pos = -1);
  /*
  Sets/gets syntax higlighting
  */
  VDKReadWriteValueProp<VDKEditor,bool> Syntax;

  /*!
    Sets/gets text insertion position expressed in chars from text
    beginning. (counting from 0, gets -1 on failure)
   */
  VDKReadWriteValueProp<VDKEditor,int>   Pointer;
  /*!
    Sets/gets text insertion position expressed in column offset
   */
  VDKReadWriteValueProp<VDKEditor,int>   Column;
  /*!
    Sets/gets text insertion position expressed in lines
   */
  VDKReadWriteValueProp<VDKEditor,int>   Line;
  /*
  Gets buffer length in chars
  */
  VDKReadOnlyValueProp<VDKEditor,unsigned int> Length;
  /*
  Sets/gets text view editable
  */
  VDKReadWriteValueProp<VDKEditor,bool> Editable;
  /*
  Sets/gets tab stops
  */
  VDKReadWriteValueProp<VDKEditor,int> TabStop;
  /*
  Sets/gets max undo (dummy for now)
  */
  VDKReadWriteValueProp<VDKEditor,unsigned int> MaxUndo;
  /*
  Sets/gets text line auto select (dummy for now)
  */
  VDKReadWriteValueProp<VDKEditor,bool> LineAutoSelect;
  /*
  Sets/gets text show line numbers (dummy for now)
  */
  VDKReadWriteValueProp<VDKEditor,bool> ShowLineNumbers;
  /*!
  Gets first visible line (lines are counted from 0)
  */
  VDKReadOnlyValueProp<VDKEditor,int> FirstVisibleLine;
  /*!
  Gets last visible line (lines are counted from 0)
  */
  VDKReadOnlyValueProp<VDKEditor,int> LastVisibleLine;
  /*!
    Sets/gets modified flag
  */
  VDKReadWriteValueProp<VDKEditor,bool>   Changed;
  /*!
    Load text buffer with a file
    \param filename
  */
  bool LoadFromFile(const char* filename);
  /*!
  Clears text buffer deleting all text.
  */
  void Clear();
  /*!
  Returns a text segment
  \param start starting position
  \param end ending position, if -1 all text buffer from start to end will
  be returned.
  
  \par Tip
  Invisible chars won't be included.
  Returned address should be g_free()'d by user.
  */
  gchar* GetChars(int start = 0, int end = -1);
  /*!
  Save buffer to file
  */
  bool SaveToFile( const char* filename);
  // dummy
  bool Undo();
  /*!
    Inserts a new line at insertion point
  */
  void Eol() { TextInsert("\n"); }
  /*!
    Inserts text at cursor position.
    \param txt null terminating string to be inserted
    \param nchars how many chars have to be inserted (-1 means all)
  */
  void TextInsert(const char* txt, int nchar = -1);
  /*!
  Forward delete chars from insertion point
  */
  void  ForwardDelete(int nchars);
  /*!
  Backward delete chars from insertion point
  */
  void  BackwardDelete(int nchars);
  /*!
  Answer if a line is visible or not
  line are counted from 0
  \param line
  */
  bool IsLineVisible(int line)
    { 
      return (line >= FirstVisibleLine) && 
      (line <= LastVisibleLine);
    }
  /*!
  Gets line number at a buffer position
  \param offset buffer offset position (counting from 0)
  on error returns -1
  */
  int GetLineAtOffset(int offset);
  /*!
  Install syntax table. If a color arg is left to NULL no higligth will
  be done on that word set, if a font arg is left to NULL makes default
  font to be used.
  \param key_color  color for language keywords
  \param key_font   related font
  \param gtk_color  color for gtk_xxx_xxx and VDK functions/members 
  \param gtk_font   related font
  \param macro_color color for macros
  \param macro_font  related font
  \param pp_color  color for prepocessor directives
  \param pp_font   related font
  \param const_color color for constants (numbers,chars,strings)
  \param const_font related font
  \param comment_color for remarks
  \param comment_font related font
  */
  void InstallSyntaxTable (VDKColor *key_color,
			       VDKFont  *key_font,
			       VDKColor *gtk_color,
   			       VDKFont  *gtk_font,
			       VDKColor *macro_color,
   			       VDKFont  *macro_font,
			       VDKColor *pp_color,
   			       VDKFont  *pp_font,
          	       VDKColor *const_color,
   			       VDKFont  *const_font,
                      VDKColor *comment_color,
   			       VDKFont  *comment_font );
  /*!
    Clear syntax table
  */
  void ClearSyntaxTable();
  /*!
  Scrolls to a pointer pos or (default) to current
  pointer position, leaving <margin> pixels free
  */
  void ScrollToPos (int pointer = -1, int margin = 0);
  /*!
  Scrolls to a line,column leaving <margin> pixels free
  */
  void ScrollToLine(int line, int col, int margin = 0);
  /*!
  Select text from start to end position
  */
  void SelectText(int start, int end);
  /*!
  Unselect any previous selected text
  */
  void UnselectText();
  /*!
    Add an icoon for line markers
    \param image a VDKPixbuf to be displayed
    \param icon_key an unique string as image id
    \param overwite if true non unique keys will have icons overwritten
  */
  bool AddMarkIcon(VDKPixbuf* image, const char * icon_key, bool overwrite = true);
  /*!
    Add a mark on line numbers
    \param line where mark will be displayed
    \param icon_key an unique string as image id
  */
  void AddLineMark(int line, const char* icon_key);
  /*!
    Remove  a mark on line numbers
    \param line where mark will be removed from
    \param icon_key
  */
  void RemoveLineMark(int line, const char* icon_key);
  /*!
    Remove  all marks on line numbers
    \param line where marks will be removed from
  */
void RemoveLineMarks(int line);
  /*!
    Remove  all markers
  */
  void RemoveAllLineMarks();
  /*
  properties setting/getting functions
  */
  void SetSyntax(bool f);
  void SetPointer(int p);
  int GetPointer();
  void SetLine(int r);
  int GetLine();
  void SetTabStop(int r);
  int GetTabStop();
  void SetColumn(int r);
  int GetColumn();
  unsigned int GetLength();
  bool GetEditable();
  void SetEditable(bool f);
  void SetShowLineNumbers(bool f);
  bool GetShowLineNumbers(void);
  int GetFirstVisibleLine();
  int GetLastVisibleLine();
  bool GetChanged();
  void SetChanged(bool f);
  void SetMaxUndo(int );
};
/*
showed hints forms
*/
class Tipwin: public VDKForm
{
  VDKLabel*  label;  
  char* tip;
public:
  Tipwin(VDKForm* owner, char* tip):
    VDKForm(owner,NULL,v_box,GTK_WINDOW_POPUP),tip(tip)
    {}
  ~Tipwin() {}
  void Setup(void);

};
#endif
