//
// "$Id: DiffView.h 407 2006-11-13 18:54:02Z mike $"
//
// DiffView widget definitions.
//
// Copyright 2005-2006 by Michael Sweet.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License v2 as published
// by the Free Software Foundation.
//
// 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.
//

#ifndef _DiffView_h_
#  define _DiffView_h_
#  include <FL/Fl.H>
#  include <FL/Fl_Group.H>
#  include <FL/Fl_Scrollbar.H>

#  if defined(WIN32)
#    include <io.h>
#  else
#    include <unistd.h>
#  endif // WIN32


//
// DiffView widget to view file differences...
//

class DiffView : public Fl_Group
{
  enum
  {
    IDLE = 0,				// Not doing anything
    SCROLLING = 1,			// Scrolling
    SELECTING = 2,			// Selecting text
    UPARROW = 3,			// Holding the up arrow
    DOWNARROW = 4			// Holding the down arrow
  };

  struct DiffLine
  {
    char	*left,			// First file's line
		*dleft,			// Display version
		*right,			// Second file's line
		*dright;		// Display version
    bool	changed;		// This line is changed?
    int		start,			// Start of changes
		end;			// End of changes
  };

  int		alloc_,			// Allocated lines
		count_;			// Number of lines in buffer
  bool		directories_;		// True if we are comparing directories
  DiffLine	**lines_;		// Lines in buffer
  char		linefmt_[16];		// Line number format
  int		linenum_;		// Width of line numbers
  int		maxwidth_;		// Maximum width of lines
  int		select_start_,		// Start of current selection
		select_end_;		// End of current selection
  bool		select_right_,		// Select the right side?
		showlinenum_,		// Show line numbers?
		ignoreblanks_;		// ignore blanks during diff ?
  int		state_,			// Scroll/selecting state
		tabwidth_;		// Width of tabs
  Fl_Color	textcolor_;		// Text color
  uchar		textfont_,		// Text font
		textsize_;		// Text size
  int		topline_;		// Top position

  Fl_Scrollbar	hscroll1_,		// Horizontal scrollbar for first file
		hscroll2_;		// Horizontal scrollbar for second file

  void		add_line(const char *left, const char *right, bool changed,
		         int pos = -1);
  void		draw();
  char		*expand_tabs(const char *s);
  static void	scroll_cb(Fl_Scrollbar *s, DiffView *d);
  static void	timeout_cb(DiffView *d);

  public:

		DiffView(int X, int Y, int W, int H, const char *L = 0);
		~DiffView();

  void		clear();
  int		count() const { return (count_); }
  bool		directories() const { return (directories_); }
  int		handle(int event);
  const char	*left(int l) { return (lines_[l]->left); }
  bool		line_changed(int l) { return (lines_[l]->changed); }
  bool		load(const char *file1, const char *file2);
  void		resize(int X, int Y, int W, int H);
  const char	*right(int l) { return (lines_[l]->right); }
  void		select(int s, int e, bool r);
  int		select_end() const { return (select_end_); }
  int		select_start() const { return (select_start_); }
  char		*selection();
  int		selection_length();
  void		showline(int l);
  void		showlinenum(bool b) { showlinenum_ = b; }
  bool		showlinenum() const { return (showlinenum_); }
  void		ignoreblanks(bool b) { ignoreblanks_ = b; }
  bool		ignoreblanks() const { return (ignoreblanks_); }
  void		tabwidth(int t) { tabwidth_ = t; }
  int		tabwidth() const { return (tabwidth_); }
  void		textcolor(Fl_Color c) { textcolor_ = c; }
  Fl_Color	textcolor() const { return (textcolor_); }
  void		textfont(uchar f) { textfont_ = f; }
  uchar		textfont() const { return (textfont_); }
  void		textsize(uchar s) { textsize_ = s; }
  uchar		textsize() const { return (textsize_); }
  int		topline() const { return (topline_ / textsize_); }
};


#endif // !_DiffView_h_

//
// End of "$Id: DiffView.h 407 2006-11-13 18:54:02Z mike $".
//
