// This may look like C code, but it is really -*- C++ -*-

//<copyright>
// 
// Copyright (c) 1994
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// original version:
// Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
// Copyright (c) 1991 Silicon Graphics, Inc.
// 
//</copyright>


//<file>
//
// File:        textb.h - interface to text browser (r/o text editor)
//
// Created:     10 Oct 94   Michael Pichler
//
// Changed:     13 Apr 95   Michael Pichler
//
//
//</file>


#ifndef harmony_widgets_textb_h
#define harmony_widgets_textb_h

#include "libwidgets.h"

class EditLabel;
class RString;
class TxtBrAdjustable;

#define SMOOTHSCROLL
/* for tests easy switching between IV's TBScrollBox and SmoothTBScrollBox */
#ifdef SMOOTHSCROLL
#define TBSCROLLBOX SmoothTBScrollBox
#else
#define TBSCROLLBOX TBScrollBox
#endif

#include <InterViews/input.h>

class Adjustable;
class FontSet;
class Color;
class PolyGlyph;
class SelectionManager;
class TextBrowser_SelectionCallback;
class TBSCROLLBOX;
class WidgetKit;

class TextBrowserLines;  // list of EditLabels


//<class>
//
// Name: TextBrowser
//
// Purpose: Glyph for showing and scrolling several line of text
//
// Style name: TextBrowser
//
// attributes:  *** in work ***
//
// - font            label font
// - foreground      label foreground colour
// - flat            glyph background (inset frame)
// - cursorColor     cursor colour (default: foreground)
// - selectionColor  colour of selection bar (default: foreground)
// - inverseColor    colour of selected char's (default: background)
//
//</class>


class TextBrowser: public InputHandler
{
  public:
    TextBrowser (                       // constructor
      WidgetKit& kit,                   //   kit
      int size = 10,                    //   estimation of line numbers (dynamic list)
      const char* stylename = nil,      //   style name (default: TextBrowser)
      const char* aliasname = nil       //   alias name (default: FieldBrowser)
    );

    virtual ~TextBrowser ();

    Adjustable* adjustableY ();         // vertical adjustable
    Adjustable* adjustableX ();         // horizontal adjustable

    virtual void appendLine (           // append one line
      const char* text
    );

    virtual void prependLine (          // prepend one line
      const char* text
    );

    virtual void clearText ();          // clears (deletes) text

    virtual GlyphIndex numLines () const;
                                        // number of lines

    void setText (                      // set text
      const char* text                  //   lines separated by '\n'
    ) { clearText ();  appendText (text); }

    virtual void appendText (           // append several lines
      const char* text                  //   lines separated by '\n'
    );

    void scrollTo (Coord horoffset);    // change horicontal offset
    void scrollToCursor ();             // scroll, so that cursor is visible
    void cursorPosition (long line, int col, int sel);  // set cursor/mark position
    int cursorLine() const { return cursorline_; }
    int cursorCol() const { return cursorcol_; }
    void attractMark (long line, int col); // mark should be nearer line
    virtual void showCursor (long /*line*/) {};
    virtual void hideCursor (long /*line*/) {};

    // get text
    virtual void getText(RString&) const;       // get whole text (lines separated by '\n'
    virtual const char* getLine(long i) const;  // get i-th line of text

    // cut and paste
    void copySelection (const Event&);
    virtual void pasteSelection (const Event&)  { }
    void paste (SelectionManager*);
    void copy (SelectionManager*);
    void lose (SelectionManager*);  // unhighlight
    void stopSelecting ();

    // InputHandler
    virtual void allocate (Canvas*, const Allocation&, Extension&);
    virtual void press(const Event&);
    virtual void drag(const Event&);
    virtual void release(const Event&);
    virtual void double_click(const Event&);
    virtual void keystroke(const Event&);  // scrolling
    virtual InputHandler* focus_in();
    virtual void focus_out();

  protected:
    boolean selection() const {
      return (cursorline_ != markerline_) || (cursorcol_ != markercol_);
    }

    TBSCROLLBOX* box_;  // body
    TextBrowserLines* lines_;
    long cursorline_;
    long markerline_;
    int cursorcol_;
    int markercol_;
    Coord maxwidth_;
    Coord horoffset_;
    boolean insertmode_;
    boolean focus_;     // TextBrowser has focus
    boolean empty_; // flag if editor is (logically) empty (it always
                    // contains at least one empty line

    EditLabel* newLine (const char* text);
    void breakLine ();
    void reallocate ();
    void notifyX ();
    void removeDummy();

  private:
    TxtBrAdjustable* hadj_;
    WidgetKit* kit_;
    int button_;  // mouse button
    TextBrowser_SelectionCallback* copy_;
    TextBrowser_SelectionCallback* lose_;
    Coord allwidth_;

    // attributes (see EditLabel for their meanings)
    const FontSet* fontset_;
    const Color* fgcolor_;
    const Color* csrcolor_;
    const Color* selcolor_;
    const Color* invcolor_;

    boolean dragged_;
    Glyph* hscrollbar_;
    Glyph* vscrollbar_;
    PolyGlyph* vbox_;
    PolyGlyph* hbox1_;
    PolyGlyph* hbox2_;

    Coord press_x_, press_y_;
};  // TextBrowser



#endif
