dslinux/user/pixil/libs/flek/Flek FArcball_Control.H FBase.H FDate.H FDolly_Control.H FFile.H FImage.H FJPEG.H FMatrix3x3.H FMatrix4x4.H FPNM.H FQuaternion.H FSGI.H FSocket.H FTrans_Control.H FTransformation.H FVector.H FVector2.H FVector3.H FVector4.H FXml.H FZoom_Control.H Fl_App_Window.H Fl_Better_Window.H Fl_Calendar.H Fl_Dockable_Window.H Fl_Frametab.H Fl_Gl_Arcball_Window.H Fl_Stock.H Fl_Time.H Fl_Toggle_Node.H Fl_Toggle_Node_Base.H Fl_Toggle_Tree.H Fl_Toggle_Tree_Base.H Flv_CStyle.H Flv_List.H Flv_Style.H Flv_Table.H Flve_Check_Button.H Flve_Combo.H Flve_Input.H export.h gl.H iostream.H math.H types.H

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:24:52 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/libs/flek/Flek
In directory antilope:/tmp/cvs-serv11916/libs/flek/Flek

Added Files:
	FArcball_Control.H FBase.H FDate.H FDolly_Control.H FFile.H 
	FImage.H FJPEG.H FMatrix3x3.H FMatrix4x4.H FPNM.H 
	FQuaternion.H FSGI.H FSocket.H FTrans_Control.H 
	FTransformation.H FVector.H FVector2.H FVector3.H FVector4.H 
	FXml.H FZoom_Control.H Fl_App_Window.H Fl_Better_Window.H 
	Fl_Calendar.H Fl_Dockable_Window.H Fl_Frametab.H 
	Fl_Gl_Arcball_Window.H Fl_Stock.H Fl_Time.H Fl_Toggle_Node.H 
	Fl_Toggle_Node_Base.H Fl_Toggle_Tree.H Fl_Toggle_Tree_Base.H 
	Flv_CStyle.H Flv_List.H Flv_Style.H Flv_Table.H 
	Flve_Check_Button.H Flve_Combo.H Flve_Input.H export.h gl.H 
	iostream.H math.H types.H 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: Fl_Dockable_Window.H ---
/* -*-C++-*- 

   "$Id: Fl_Dockable_Window.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FL_DOCKABLE_WINDOW_H_
#define _FL_DOCKABLE_WINDOW_H_

#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>

#define FL_UNDOCK     999999999
#define FL_DOCK       99999999
#define FL_PACK_DOCK  9999999
#define FL_DOCK_DELTA 10

#define FL_SHOVABLE 1
#define FL_DRAGABLE 2

/** @package libflek_ui
 * Fl_Gripper is a little button that looks like you can grab it
 * (to drag something around with) or push it, depending on the
 * gripper type.
 * Used by Fl_Dockable_Window.
 */
class Fl_Gripper : public Fl_Button {
private:
  int x_down;
  int y_down;
  int x_first;
  int y_first;
  unsigned char _grippertype;

protected:
  void draw();
  int handle(int event);

public:
  Fl_Gripper(int x, int y, int w, int h, const char *l = 0) : 
    Fl_Button(x, y, w, h, l) {
  }

  /* Sets the type of gripper.
   * If you set the type to FL_SHOVABLE, you get a
   * gripper button that cannot be dragged, but can be pushed to "shove" the
   * toolbar to the other docking location.
   * If you set the type to FL_SHOVABLE | FL_DRAGABLE, the gripper looks
   * dragable, and is both dragable and shovable.
   */
  void grippertype(unsigned char t); 
  unsigned char grippertype();
};

/** @package libflek_ui
 * Fl_Dockable_Window is a window that can be docked onto a window 
 * that accepts Fl_Dockable_Windows, such as an Fl_App_Window.
 * <p><img src="Fl_Dockable_Window.png">
 */
class Fl_Dockable_Window : public Fl_Window {
protected:
  Fl_Gripper* gripper;
  Fl_Window* contents;
  static long gripper_width;
  short _docked;
  int uw_;
  int uh_;
  void Fl_Dockable_Window::create_dockable_window();

public:
  static Fl_Dockable_Window* current;

  /**
   * Constructs a dockable window.
   */
  Fl_Dockable_Window(int w, int h, const char *l = 0);
  Fl_Dockable_Window(int x, int y, int w, int h, const char *l = 0);

  /**
   * Begin adding new widgets to the contents window.
   */
  void begin() { Fl_Group::current(contents); }

  /**
   * Undocks the group to screen coordinates (x, y).
   */
  void undock(int x = -1, int y = -1);  

  /**
   * Sets or tests whether window is docked or not.
   */
  void docked(short r) { _docked = r; }  
  short docked() { return _docked; }
  
  /**
   * Sets the look and action of the gripper.  See Fl_Gripper::grippertype()
   * for more information.
   */
  void grippertype(unsigned char t); 
  unsigned char grippertype();

  int handle(int);
  void show();
};

#endif

--- NEW FILE: Fl_Toggle_Node_Base.H ---
#ifndef _FL_NODE_H_
#define _FL_NODE_H_

class Fl_Toggle_Node_Base {

  friend class Fl_Toggle_Tree_Base;

public:

  Fl_Toggle_Node_Base () {
    prev_ = 0;
    next_ = 0;
    sub_ = 0;
    vsub_ = 0;
    up_ = 0;
    opened_ = 0;
  }

  inline Fl_Toggle_Node_Base* previous() { return prev_; }
  inline Fl_Toggle_Node_Base* next() { return next_; }
  inline Fl_Toggle_Node_Base* child() { return sub_; }
  inline Fl_Toggle_Node_Base* visible_child() { return vsub_; }
  inline Fl_Toggle_Node_Base* parent() { return up_; }

protected:

  Fl_Toggle_Node_Base* prev_;
  Fl_Toggle_Node_Base* next_;
  Fl_Toggle_Node_Base* sub_;
  Fl_Toggle_Node_Base* vsub_;
  Fl_Toggle_Node_Base* up_;

  int opened_;

};

#endif

--- NEW FILE: Fl_Frametab.H ---
/* Fl_Frametab for WidgetSet, Copyright (c) 1998 curtis Edwards (curt1 at jps.net)
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both the
 * copyright notice and this permission notice appear in supporting
 * documentation.  All work developed as a consequence of the use of
 * this program should duly acknowledge such use. No representations are
 * made about the suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
   Description	-  Raps widgets in a managable group giving
                hiding and showing of grouped widgets
*/

#ifndef Fl_FTAB_H
#define Fl_FTAB_H

#include <FL/Fl.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Light_Button.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/Fl_Group.H>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MINFRAMEHEIGHT      26
#define MINFRAMEPIXHEIGHT   8   //horz mode
#define MINFRAMEPIXWIDTH    36
#define MINFRAMEPIXINDENT   46 //for label
#define MINFRAMEINDENT      12


class Fl_Frametab : public Fl_Group 
{
public:
  enum { // values for type(int)
    TRIANGLE = 0,
    BITMAP   = 1
  };
   int        _hilight;          //is hilighted (FL_ENTER/LEAVE) version 2- Curtis99
   int        _hilight_col;     //storage for hilight color
   int        _openSize;        //size when tab closed version 2- Curtis99
   int        _openLabelHide;   //true/false if label should be hidden when open/expanded
   int        _isopen;          //TRUE/FALSE if frame open/closed

   void  draw();          //main draw
   int   handle(int);     //events,for pushing of frame area
   void  close();
   void  open();
   int   isOpen()                 {return _isopen;       }
   void  hilight_color(int col)   { _hilight_col = col;  }
   int   hilight_color()          { return _hilight_col; }
   void  openSize(int siz)        { _openSize = siz;     }
   int   openSize()               {return _openSize;     }
   void  openLabelHide(int yn)    { _openLabelHide = yn; }
   int   openLabelHide()          {return _openLabelHide;}
   int   openDiff()               {if(!_isopen) return (_openSize-(type() ? MINFRAMEPIXHEIGHT : MINFRAMEHEIGHT))*-1; else return (_openSize-(type() ? MINFRAMEPIXHEIGHT : MINFRAMEHEIGHT));}
   Fl_Frametab(int x,int y,int w,int h,char *);

};
#endif

--- NEW FILE: Flv_CStyle.H ---
//	======================================================================
//	File:    Flv_Style.H - Flv_Style definition
//	Program: Flv_Style - FLTK Virtual List/Table Styles Widget
//	Version: 0.1.0
//	Started: 11/21/99
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	This has nothing to do with styles and themes being implemented
//	in FLTK 2.0 the name is just coincidental.  We will however try to use
//	true 2.0 style information as much as possible.
//
//	The virtual style classes are designed to handle style informaton for
//	the Flv_List class and derivatives.  (Although anyone could use
//	them)  The concept of virtual styles is to create a trickle down style
//	protocol that allows only defined attributes to be created.  The trickle
//	down is as follows:
//	Global style
//	Row style
//	Column style
//	Cell style
//
//	Note: Global Style will be a Flv_Cell_Style since that will
//				maximally define attributes for the table.
//	The global style will inherit whatever the current style information
//	dictates, so it will be completely defined.  (Whether it used in 1.x or 2.x
//	FLTK.  From there we will only require definition of styles where you
//	need them.  For instance:
//	If you want to override the header and footer styles and redefine
//	5 column layouts, you will have a total of 8 styles defined:
//	1 global style (always defined)
//	2 row styles
//	5 column styles
//
//	Hopefully only requiring the styles you really want to define will help
//	offset the fact that it just takes memory to do this... :)
//	Of course you could choose not to define any styles and then you'll just
//	have the global style defined. But you know the table is pretty bare...
//	======================================================================

#ifndef FLV_CSTYLE_H
#define FLV_CSTYLE_H

#include <FL/Fl.H>
#ifdef FLEK_FLTK_2
#include <FL/Fl_Font.H>
#endif
#include <Flek/Flv_Style.H>

class Flv_CStyle : public Flv_Style
{
public:
	Flv_CStyle();

	int x(void)  const											//	Get x
		{	return vx;	};
	int x(int n);														//	Set x

	int y(void)  const											//	Get y
		{	return vy;	};
	int y(int n);														//	Set y

	const Flv_CStyle &operator=(const Flv_CStyle &n);
private:
	int vx, vy;															//	Row relative cell location
};

#endif


--- NEW FILE: FZoom_Control.H ---
/* -*-C++-*- 

   "$Id: FZoom_Control.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FZOOM_CONTROL_H_
#define _FZOOM_CONTROL_H_

#include <Flek/FVector3.H>
#include <Flek/FMatrix4x4.H>
#include <Flek/math.H>

/**
 * @package libflek_gl
 * 
 * Class for a zoom controller.
 * Implements zooming by scaling in the current XY plane.
 */
class FZoom_Control {
  
protected:
  
  // Current transformation matrix:
  FMatrix4x4 mNow;

  // Drag state
  bool Dragging;

  // Mouse x coordinate
  double vNowx, vDownx;

  FVector3 zNow, zDown;

public:

  /**
   * Default constructor.
   */
  FZoom_Control()
    : mNow(), Dragging(false), vNowx(0.0), vDownx(0.0), zNow(1,1,1), zDown(1,1,1)
  {}

  /**
   * Copy constructor.
   */
  FZoom_Control(const FZoom_Control& tc)
    : mNow(tc.mNow), Dragging(tc.Dragging), vNowx(tc.vNowx), vDownx(tc.vDownx),
      zNow(tc.zNow), zDown(tc.zDown)
  {}

  /**
   * Destructor.
   */
  ~FZoom_Control() {}

  /**
   * Assignment operator.
   */
  FZoom_Control& operator = (const FZoom_Control& tc) {
    mNow = tc.mNow; Dragging = tc.Dragging; vNowx = tc.vNowx; vDownx = tc.vDownx;
    zNow = tc.zNow; zDown = tc.zDown;
    return (*this);
  }
  
  /**
   * Reset the zoom controller to default values.
   */
  void reset (void) {
    zNow.set(1,1,1); zDown.set(1,1,1); mNow.reset();
  }
  
  /**
   * Specify mouse position.
   */
  void mouse (const FVector3& pos) {
    vNowx = pos[0];
  }

  /**
   * Specify mouse position.
   */
  void mouse (double x, double y=0.0, double z=0.0) {
    vNowx = x;
  }
  
  /**
   * Get the translation matrix.
   */
  FMatrix4x4 value (void) const {
    return mNow;
  }

  /**
   * Get the scale vector.
   */
  FVector3 zoom_value (void) const {
    return zNow;
  }
  
  /**
   * Begin a drag.
   */
  void begin_drag (void) {
    Dragging = true; 
    vDownx = vNowx;
  }
     
  /** 
   * End a drag.
   */
  void end_drag (void) {
    Dragging = false; 
    zDown = zNow;
  }
  
  /**
   * Check dragging status.
   */
  bool dragging (void) const {
    return Dragging;
  }
  
  /** 
   * Update the FVectors and FMatrices
   */
  void update (void) {
    if (Dragging) {
      zNow = zDown;
      
      // Mapping between mouse movement and scale change is as follows
      // For a mouse movement of 1.0, scale changes by a factor of 2
      // Note: This is in the transformed mouse coordinates (-1 to 1)
      // Also only the x mouse coordinate is used
      double diff = vNowx - vDownx;
      double fact = 1 + absolute (diff);
      if ( diff < 0.0 ) zNow /= fact;
      else zNow *= fact;
      
      // All 3 coordinates of the zoom FVector are changed to get proper
      // view scaling (rotate after zoom, etc.)
      
      // Fill in transposed order for GL
      mNow[0][0] = zNow[0];
      mNow[1][1] = zNow[1];
      mNow[2][2] = zNow[2];
    }
  }
};

#endif

--- NEW FILE: FMatrix4x4.H ---
/* -*-C++-*- 
   
   "$Id: FMatrix4x4.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FMATRIX_4x4_H_
#define _FMATRIX_4x4_H_

#include <Flek/FBase.H>
#include <Flek/FVector4.H>
#include <Flek/FMatrix3x3.H>

/** @package libflek_core
 * Class for a 4x4 matrix. Built from Vector4d
 * Row-major form is used. (ie) each row of the matrix
 * is a Vector3d. This makes inversion easier, since elementary
 * row operations are simplified
 */

class FMatrix4x4 : public FBase
{
public:
  
  typedef FMatrix4x4 * Ptr;
  
  /**
   * Default constructor - creates an identity matrix.
   */
  FMatrix4x4 ()
    : FBase ()
    {
      row[0].set (1.0, 0.0, 0.0, 0.0);
      row[1].set (0.0, 1.0, 0.0, 0.0);
      row[2].set (0.0, 0.0, 1.0, 0.0);
      row[3].set (0.0, 0.0, 0.0, 1.0);
    }
  
  /**
   * 1 argument constructor - from scalar, set all elements to given value
   */
  FMatrix4x4 (double scalar)
    : FBase ()
    {
      row[0] = scalar; row[1] = scalar; row[2] = scalar; row[3] = scalar;
    }
  
  /**
   * 4 argument constructor - from 4 FVector4s
   */
  FMatrix4x4 (const FVector4& r0, const FVector4& r1, const FVector4& r2, const FVector4& r3)
    : FBase ()
    {
      row[0] = r0; row[1] = r1; row[2] = r2; row[3] = r3;
    }
  
  /**
   * Copy constructor
   */
  FMatrix4x4 (const FMatrix4x4& mat)
    : FBase ()
    {
      copy_from (mat);
    }
  
  /**
   * Constructor from a 3x3 matrix
   */
  FMatrix4x4 (const FMatrix3x3& mat3)
    : FBase ()
    {
      copy_from (mat3);
    }
  
  /**
   * Destructor
   */
  virtual ~FMatrix4x4 ()
    {}
  
  /**
   * Assignment operator
   */
  FMatrix4x4& operator = (const FMatrix4x4& mat)
    {
      copy_from (mat);
      return (*this);
    }
  
  /**
   * Assignment from a FMatrix3x3
   */
  FMatrix4x4& operator = (const FMatrix3x3& mat3)
    {
      copy_from (mat3);
      return (*this);
    }
  
  /**
   * Assignment from a scalar
   */
  void operator = (double scalar)
    {
      row[0] = scalar; row[1] = scalar; row[2] = scalar; row[3] = scalar;
    }
  
  /**
   * Set the rows of the matrix to the given FVector4s
   */
  void set (const FVector4& r0, const FVector4& r1, const FVector4& r2, const FVector4& r3)
    {
      row[0] = r0; row[1] = r1; row[2] = r2; row[3] = r3;
    }
  
  void set (double scalar)
    {
      row[0] = scalar; row[1] = scalar; row[2] = scalar; row[3] = scalar;
    }
  
  /**
   * Reset the matrix to it's default state - identity
   */
  void reset (void)
    {
      row[0].set (1.0, 0.0, 0.0, 0.0);
      row[1].set (0.0, 1.0, 0.0, 0.0);
      row[2].set (0.0, 0.0, 1.0, 0.0);
      row[3].set (0.0, 0.0, 0.0, 1.0);
    }
  
  /** 
   * Make a copy of the object implement FBase class pure virtual function
   */
  virtual FBase::Ptr copy (void) const
    {
      Ptr mat = new FMatrix4x4 (*this);
      return mat;
    }
  
  /**
   * Access a row of the matrix - no range checks.
   */
  FVector4& operator [] (uint index)
    {
      return row[index];
    }
  
  /**
   * Access a row of the matrix - no range checks : const version
   */
  const FVector4& operator [] (uint index) const
    {
      return row[index];
    }
  
  /**
   * Class member functions which return the identity matrix
   */
  static FMatrix4x4 identity (void)
    {
      FMatrix4x4 imat;  // Default constructor creates an identity matrix
      return imat;
    }
  
  /**
   * Class member functions which return the identity matrix
   */
  static FMatrix4x4 I (void)
    {
      FMatrix4x4 imat;  // Default constructor creates an identity matrix
      return imat;
    }
  
  // Arithmetic assignment operators
  
  void operator += (const FMatrix4x4& mat)
    {
      for (int i=0; i < 4; ++i)
	row[i] += mat.row[i];
    }
  
  void operator -= (const FMatrix4x4& mat)
    {
      for (int i=0; i < 4; ++i)
	row[i] -= mat.row[i];
    }
  
  void operator *= (double scalar)
    {
      for (int i=0; i < 4; ++i)
	row[i] *= scalar;
    }
  
  void operator /= (double scalar)
    {
      for (int i=0; i < 4; ++i)
	row[i] /= scalar;
    }
  
  // Special functions - inverse, transpose, etc.
  
  /**
   * Find the 3x3 sub-matrix which is the co-factor for the given element
   */
  FMatrix3x3 cofactor(uint r, uint c) const
    {
      FMatrix3x3 cof;
      FVector3 cofrow;
      uint cfcol, cfrow;
      
      if ( (r > 3) || (c > 3) )
	{
	  cerr << "FMatrix3x3 FMatrix4x4 :: cofactor(int,int) : Index out of range!" << endl;
	  return cof;
	}
      
      cfrow = 0;
      for (uint i=0; i < 4; ++i)
	{
	  if ( i != r )
	    {
	      cfcol = 0;
	      for (uint j=0; j < 4; ++j)
		if ( j != c ) cofrow[cfcol++] = row[i][j];
	      cof[cfrow++] = cofrow;
	    }
	}
      return cof;
    }
  
  void transpose(void)
    {
      for (int i=0; i < 4; ++i)
	for (int j=i+1; j < 4; ++j)
	  swap(row[i][j],row[j][i]);
    }
  
  /**
   * Find the transpose of a given matrix.
   */
  friend FMatrix4x4 transpose(const FMatrix4x4& mat)
    {
      FMatrix4x4 trans (mat); trans.transpose ();
      return trans;
    }
  
  friend double determinant(const FMatrix4x4& mat)
    {
      double det = 0.0;
      
      for (int i=0; i < 3; ++i)
	det += mat[0][i] * cofsign (0, i) * determinant (mat.cofactor (0, i));
      return det;
    }
  
  /**
   * Invert the matrix. Using elementary row operations
   */
  void invert(void)
    {
      FVector4 inv[4];
      int i,j,swaprow;
      
      for (i=0; i < 4; ++i)
	inv[i][i] = 1.0;
      
      // inv will be identity initially and will become the inverse at the end
      for (i=0; i < 4; ++i)
	{
	  // i is column
	  // Find row in this column which has largest element (magnitude)
	  swaprow = i;
	  for (j=i+1; j < 4; ++j)
	    if ( fabs (row[j][i]) > fabs (row[i][i]) ) swaprow = j;
	  
	  if ( swaprow != i )
	    {
	      // Swap the two rows to get largest element in main diagonal
	      // Do this for the RHS also
	      swap (row[i], row[swaprow]); swap (inv[i], inv[swaprow]);
	    }
	  
	  // Check if pivot is non-zero
	  if ( !is_non_zero (row[i][i]) )
	    {
	      cerr << "FMatrix4x4 inverse(const FMatrix4x4&) : Singular matrix!" << endl;
	      // Return original matrix without change
	      return;
	    }
	  
	  // Divide matrix by main diagonal element to make it 1.0
	  double fact = row[i][i];
	  for (j=0; j < 4; ++j)
	    {
	      row[j] /= fact;
	      inv[j] /= fact;
	    }
	  
	  // Make non-main-diagonal elements in this column 0 using main-diagonal row
	  for (j=0; j < 4; ++j)
	    {
	      if ( j != i )
		{
		  double temp = row[j][i];
		  row[j] -= row[i]*temp;
		  inv[j] -= inv[i]*temp;
		}
	    }
	}
      
      // Main-diagonal elements on LHS may not be 1.0 now. Divide to make LHS identity
      // Last row will be 1.0
      for (i=0; i < 3; ++i)
	{
	  double pivot = row[i][i];
	  row[i] /= pivot;
	  inv[i] /= pivot;
	}
      for (i=0; i < 4; ++i)
	row[i] = inv[i];
    }
  
  /** 
   * Find the inverse of a given matrix using elementary row operations
   */
  friend FMatrix4x4 invert (const FMatrix4x4& mat)
    {
      FMatrix4x4 inv (mat); inv.invert ();
      return inv;
    }
  
  // Arithmetic operators, implemented as friend functions
  
  /**
   * Negation
   */
  friend FMatrix4x4 operator - (const FMatrix4x4& mat)
    {
      FMatrix4x4 neg;
      
      for (int i=0; i < 4; ++i)
	neg.row[i] = -mat.row[i];
      
      return neg;
    }
  
  friend FMatrix4x4 operator + (const FMatrix4x4& mat1, const FMatrix4x4& mat2)
    {
      FMatrix4x4 sum (mat1);
      sum += mat2;
      return sum;
    }
  
  friend FMatrix4x4 operator - (const FMatrix4x4& mat1, const FMatrix4x4& mat2)
    {
      FMatrix4x4 diff (mat1);
      diff -= mat2;
      return diff;
    }
  
  /**
   * Post-multiplication by a scalar.
   */
  friend FMatrix4x4 operator * (const FMatrix4x4& mat, double scalar)
    {
      FMatrix4x4 prod (mat);
      prod *= scalar;
      return prod;
    }
  
  /**
   * Pre-multiplication by a scalar.
   */
  friend FMatrix4x4 operator * (double scalar, const FMatrix4x4& mat)
    {
      FMatrix4x4 prod (mat);
      prod *= scalar;
      return prod;
    }
  
  /**
   * Division by a scalar.
   */
  friend FMatrix4x4 operator / (const FMatrix4x4& mat, double scalar)
    {
      FMatrix4x4 quot (mat);
      quot /= scalar;
      return quot;
    }
  
  /**
   * Multiplication of 2 matrices - outer product.
   */
  friend FMatrix4x4 operator * (const FMatrix4x4& mat1, const FMatrix4x4& mat2);
  
  /**
   * Element-by-element multiplication of 2 matrices.
   */
  friend FMatrix4x4 product (const FMatrix4x4& mat1, const FMatrix4x4& mat2)
    {
      FMatrix4x4 prod;
      
      prod.row[0] = product (mat1[0], mat2[0]);
      prod.row[1] = product (mat1[1], mat2[1]);
      prod.row[2] = product (mat1[2], mat2[2]);
      prod.row[3] = product (mat1[3], mat2[3]);
      
      return prod;
    }
  
  /**
   * Post-multiplication by a FVector4. Vector is assumed to be a column vector.
   */
  friend FVector4 operator * (const FMatrix4x4& mat, const FVector4& vec)
    {
      FVector4 prod;
      
      prod.set (mat.row[0]*vec, 
		mat.row[1]*vec, 
		mat.row[2]*vec, 
		mat.row[3]*vec);
      return prod;
    }
  
  /**
   * Pre-multiplication by a FVector4. Vector is assumed to be a row vector.
   */
  friend FVector4 operator * (const FVector4& vec, const FMatrix4x4& mat);
  
  /**
   * Multiplication of two FVector4s to produce a FMatrix4x4 - outer product
   * or tensor product of two Vectors.  
   * Same as multiplying row vector (v1) with column vector (v2)
   */
  friend FMatrix4x4 operator ^ (const FVector4& v1, const FVector4& v2)
    {
      FMatrix4x4 prod;
      
      prod.row[0] = v1[0]*v2;
      prod.row[1] = v1[1]*v2;
      prod.row[2] = v1[2]*v2;
      prod.row[3] = v1[3]*v2;
      
      return prod;
    }
  
  friend void swap (FMatrix4x4& mat1, FMatrix4x4& mat2)
    {
      for (int i=0; i < 4; ++i)
	swap (mat1.row[i], mat2.row[i]);
    }
  
  /** 
   * Multiply self with another matrix. Simply calls above defined friend 
   * function.
   */
  void operator *= (const FMatrix4x4& mat)
    {
      FMatrix4x4 prod = (*this) * mat;
      *this = prod;
    }

  /**
   * Fill an array with contents of the matrix
   * Row - major form -> Row 1 == { array[0], array[1], array[2], array[3] }
   */
  void fill_array_row_major (double array[16]) const
    {
      int index=0;
      for (int i=0; i < 4; ++i)
	{
	  row[i].get (array[index],
		      array[index+1],
		      array[index+2],
		      array[index+3]);
	  index += 4;
	}
    }

  /**
   * Fill an array with contents of the matrix
   * Row - major form -> Column 1 == { array[0], array[1], array[2], array[3] }  
   */
  void fill_array_column_major (double array[16]) const
    {
      int index=0;
      for (int i=0; i < 4; ++i)
	{
	  row[i].get (array[index], 
		      array[index+4], 
		      array[index+8], 
		      array[index+12]);
	  index += 1;
	}
    }
  
  friend ostream& operator << (ostream& o, const FMatrix4x4& mat)
    {
      o << "[ " << mat.row[0] << "," << endl
	<< "  " << mat.row[1] << "," << endl
	<< "  " << mat.row[2] << "," << endl
	<< "  " << mat.row[3] << " ]" << endl;
      return o;
    }
  
  friend istream& operator >> (istream& i, FMatrix4x4& mat)
    {
      char rowsep, dummy;
      i >> dummy >> mat.row[0] >> rowsep
	>> mat.row[1] >> rowsep
	>> mat.row[2] >> rowsep
	>> mat.row[3] >> dummy;
      return i;
    }
protected:
  
  FVector4   row[4];                                // 4 rows of the matrix
  
  /**
   * Copy values from another matrix
   */
  void copy_from (const FMatrix4x4& mat)
    {
      for (int i=0; i < 4; ++i)
	row[i] = mat.row[i];
    }
  
  /**
   * Copy from a 3x3 matrix. 4th row and column elements are all set to 0
   */
  void copy_from (const FMatrix3x3& mat3)
    {
      for (int i=0; i < 3; ++i)
	row[i] = mat3[i];
    }
};

#endif // #ifndef FMatrix_4x4_H_

--- NEW FILE: Fl_Time.H ---
// Fl_Time.h
// Header file for the time Widget class
//
// Copyright (C) 2000 Softfield Research Ltd.
//
// 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.

#ifndef __TIME_WIDGET_H
#define __TIME_WIDGET_H

#include "sys/time.h"
#include "unistd.h"
#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Repeat_Button.H>
#include <FL/Fl_Input.H>

#define FL_TIME_24HOUR 0
#define FL_TIME_12HOUR 1

/** @package libflek_ui
 * Fl_Time is a widget that allows a user to select a time
 * (hour and minute). 
 * <p><img src="Fl_Time.png">
 */
class Fl_Time : public Fl_Group {

private:
  Fl_Repeat_Button* button_decrease_hour;
  Fl_Repeat_Button* button_decrease_minute;
  Fl_Input*  input_time;
  Fl_Repeat_Button* button_increase_minute;
  Fl_Repeat_Button* button_increase_hour;
  
  struct timeval current_tv;
  struct timeval display_tv;
  char time_string[20];
  bool last_valid;
  
  int look_;
  
  static void input_changed_cb(Fl_Widget* widget, void* data);
  static void button_cb(Fl_Widget* widget, void* data);
  
public:
  /**
   * The constructor for an empty Fl_Time widget.
   */
  Fl_Time(int x, int y, int w, int h, char *l=0); 

  /**
   * Gets the hour.
   *
   * @return The hour associated with this widget.
   */  
  int hour();

  /**
   * Sets the hour.
   *
   * @param hour The hour associated with this widget.
   */  
  void hour(int value);
  
  /**
   * Gets the minute.
   *
   * @return The minute associated with this widget.
   */  
  int minute();

  /**
   * Sets the minute.
   *
   * @param minute The minute associated with this widget.
   */  
  void minute(int value);
  
  // Be sure to run this after using hour and min to change the clock value.
  void redisplay();
  
  /**
   * Sets the minute and hour at the same time.
   *
   * @param minute The minute associated with this widget.
   * @param hour The hour associated with this widget.
   */  
  void value(int h, int m);

  /**
   * Sets the minute and hour to the system minute and hour.
   */
  void current_time();

  /**
   * Refreshes the widget.
   */
  void refresh();

  /**
   * Sets the size of the label text which is used for the M+,
   * M-, Y+, and Y- labels.
   *
   * @param size The size of the label font.
   */  
  void labelsize(int size);

  /**
   * Sets the label font which is used for the M+,
   * M-, Y+, and Y- labels.
   *
   * @param font The label font.
   */  
  void labelfont(Fl_Font font);

  /**
   * Sets the label color which is used for the M+,
   * M-, Y+, and Y- labels.
   *
   * @param font The label color.
   */  
  void labelcolor(Fl_Color color);

  /**
   * Sets the size of the text which is used to display
   * the set time.
   *
   * @param size The size of the text font.
   */  
  void textsize(int size);

  /**
   * Sets the font of the text which is used to display
   * the set time.
   *
   * @param font The font of the text font.
   */  
  void textfont(Fl_Font);

  /**
   * Sets the color of the text which is used to display
   * the set time.
   *
   * @param color The color of the text font.
   */  
  void textcolor(Fl_Color);
  
  /**
   * Gets the size of the label text which is used for the M+,
   * M-, Y+, and Y- labels.
   *
   * @return The size of the label font.
   */  
  int labelsize();

  /**
   * Gets the label font which is used for the M+,
   * M-, Y+, and Y- labels.
   *
   * @return The label font.
   */  
  Fl_Font labelfont();

  /**
   * Gets the label color which is used for the M+,
   * M-, Y+, and Y- labels.
   *
   * @return The label color.
   */  
  Fl_Color labelcolor();
  
  /**
   * Gets the size of the text which is used to display
   * the set time.
   *
   * @return The size of the text font.
   */  
  int textsize();

  /**
   * Gets the font of the text which is used to display
   * the set time.
   *
   * @return The font of the text font.
   */  
  Fl_Font textfont();

  /**
   * Gets the color of the text which is used to display
   * the set time.
   *
   * @return The color of the text font.
   */
  Fl_Color textcolor();

  /**
   * Determines if the entered time is a recognized format.
   *
   * @return True if it is a valid time format, otherwise false.
   */  
  bool valid();	
};

#endif

--- NEW FILE: FVector.H ---
/* -*-C++-*- 

   "$Id: FVector.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FVECTOR_H_
#define _FVECTOR_H_

/*
 * Common stuff for all the static Vector classes
 * Forward declarations for all the classes is included here, along with 
 * common include files and prototypes for functions that use different kinds
 * of Vectors.
 */

// Common include files
#include <stdlib.h>
#include <Flek/math.H>
#include <Flek/FBase.H>
#include <Flek/iostream.H>

// Forward declarations
class FVector2;
class FVector3;
class FVector4;
class FGl;

// Function prototypes
FVector3 operator % (const FVector2& vec1, const FVector2& vec2);
FVector3 operator % (const FVector3& vec1, const FVector2& vec2);
FVector3 operator % (const FVector2& vec1, const FVector3& vec2);

#endif // #ifndef FVECTOR_H_


--- NEW FILE: Flv_Style.H ---
//	======================================================================
//	File:    Flv_Style.H - Flv_Style definition
//	Program: Flv_Style - FLTK Virtual List/Table Styles Widget
//	Version: 0.1.0
//	Started: 11/21/99
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	This has nothing to do with styles and themes being implemented
//	in FLTK 2.0 the name is just coincidental.  We will however try to use
//	true 2.0 style information as much as possible.
//
//	The virtual style classes are designed to handle style informaton for
//	the Flv_List class and derivatives.  (Although anyone could use
//	them)  The concept of virtual styles is to create a trickle down style
//	protocol that allows only defined attributes to be created.  The trickle
//	down is as follows:
//	Global style
//	Row style
//	Column style
//	Cell style
//
//	Note: Global Style will be a Flv_Cell_Style since that will
//				maximally define attributes for the table.
//	The global style will inherit whatever the current style information
//	dictates, so it will be completely defined.  (Whether it used in 1.x or 2.x
//	FLTK.  From there we will only require definition of styles where you
//	need them.  For instance:
//	If you want to override the header and footer styles and redefine
//	5 column layouts, you will have a total of 8 styles defined:
//	1 global style (always defined)
//	2 row styles
//	5 column styles
//
//	Hopefully only requiring the styles you really want to define will help
//	offset the fact that it just takes memory to do this... :)
//	Of course you could choose not to define any styles and then you'll just
//	have the global style defined. But you know the table is pretty bare...
//	======================================================================

#ifndef FLV_STYLE_H
#define FLV_STYLE_H

#include <FL/Fl.H>
#ifdef FLEK_FLTK_2
#include <FL/Fl_Font.H>
#endif

//	Border constants
#define FLVB_NONE						0
#define FLVB_LEFT						1
#define FLVB_TOP						2
#define FLVB_RIGHT					4
#define FLVB_BOTTOM					8
#define FLVB_INNER_LEFT			16
#define FLVB_INNER_TOP			32
#define FLVB_INNER_RIGHT		64
#define FLVB_INNER_BOTTOM		128
#define FLVB_OUTER_VERTICALS (FLVB_LEFT|FLVB_RIGHT)
#define FLVB_OUTER_HORIZONTALS (FLVB_TOP|FLVB_BOTTOM)
#define FLVB_OUTER_ALL (FLVB_VERTICALS|FLVB_HORIZONTALS)
#define FLVB_INNER_VERTICALS (FLVB_INNER_LEFT|FLVB_INNER_RIGHT)
#define FLVB_INNER_HORIZONTALS (FLVB_INNER_TOP|FLVB_INNER_BOTTOM)
#define FLVB_INNER_ALL (FLVB_INNER_VERTICALS|FLVB_INNER_HORIZONTALS)
#define FLVB_VERTICALS (FLVB_OUTER_VERTICALS|FLVB_INNER_VERTICALS)
#define FLVB_HORIZONTALS (FLVB_OUTER_HORIZONTALS|FLVB_INNER_HORIZONTALS)
#define FLVB_ALL (FLVB_OUTER_ALL|FLVB_INNER_ALL)
#define FLVB_LEFTS (FLVB_LEFT|FLVB_INNER_LEFT)
#define FLVB_TOPS (FLVB_TOP|FLVB_INNER_TOP)
#define FLVB_RIGHTS (FLVB_RIGHT|FLVB_INNER_RIGHT)
#define FLVB_BOTTOMS (FLVB_BOTTOM|FLVB_INNER_BOTTOM)

class Flv_Style;

//	Note: it is undefined behavior to insert a non-dynamically allocated
//	styles into this list!
class Flv_Style_List
{
public:
	Flv_Style_List();

	void clear(void);									//	Undefine all styles in list
  void compact(void);								//	Release any unused style memory
	void release(void);								//	Free memory for all (including cell
	Flv_Style *current(void);					//	Current node
	Flv_Style *find( int n );					//	Find value n (Random access method)
	Flv_Style *first(void);						//	Get first style
	bool insert( Flv_Style *n );			//	Add style (if doesn't exist)
	Flv_Style *next(void);						//	Next style
	Flv_Style *skip_to(int v );				//	Find value n (Sequential processing)
	Flv_Style *prior(void);						//	Previous style
	bool clear_current(void);					//	Undefine optionally release
	bool release_current(void);				//	Remove current style
	int count(void)										//	# of styles
		{	return vcount;	}
	Flv_Style &operator[](int value);	//	Note: this could be a little
																		//	weird.  It's actually going
																		//	to return a style with value
																		//	not index value.
private:
	Flv_Style **list;							//	Array of style pointers
	int vcount;														//	# of style pointers defined
	int vallocated;												//	# of style pointers allocated
	int vcurrent;													//	Current position
};

class Flv_Style
{
public:
	friend class Flv_Style_List;									//	Hack for value
	Flv_Style();
	Flv_Style( int value );

	bool all_clear(void)										//	Is all style info cleared?
		{	return (vdefined==0);	}
	void clear_all(void)										//	Clear all style info
		{	vdefined=0;	}
	bool all_defined(void)									//	Everything defined?
		{	return (vdefined&1023)==1023;	}

	const Fl_Align &align(void) const				//	Get drawing alignment
		{	return valign;	};
	const Fl_Align &align(const Fl_Align &n);	//	Set drawing alignment
	void clear_align(void);									//	Undefine drawing alignment
	bool align_defined(void) const;					//	Is drawing alignment defined?

	Fl_Color background(void) const					//	Get background color
		{	return vbackground;	};
	Fl_Color background(Fl_Color n);				//	Set background color
	void clear_background(void);						//	Undefine background color
	bool background_defined(void) const;		//	Is background defined?

  int border(void) const									//	Get borders
  	{	return vborder;	}
  int border(int n);											//	Set borders
  void clear_border(void);								//	Undefine border
  bool border_defined(void) const;				//	Is border defined?
  bool left_border(void) const						//	Left border?
  	{	return (vborder&FLVB_LEFT)==FLVB_LEFT;	}
  bool top_border(void) const							//	Top border?
  	{	return (vborder&FLVB_TOP)==FLVB_TOP;	}
  bool right_border(void) const						//	Right border?
  	{	return (vborder&FLVB_RIGHT)==FLVB_RIGHT;	}
  bool bottom_border(void) const					//	Bottom border?
  	{	return (vborder&FLVB_BOTTOM)==FLVB_BOTTOM;	}
  bool inner_left_border(void) const			//	Inner left border?
  	{	return (vborder&FLVB_INNER_LEFT)==FLVB_INNER_LEFT;	}
  bool inner_top_border(void) const				//	Inner top border?
  	{	return (vborder&FLVB_INNER_TOP)==FLVB_INNER_TOP;	}
  bool inner_right_border(void) const			//	Inner right border?
  	{	return (vborder&FLVB_INNER_RIGHT)==FLVB_INNER_RIGHT;	}
  bool inner_bottom_border(void) const		//	Inner bottom border?
  	{	return (vborder&FLVB_INNER_BOTTOM)==FLVB_INNER_BOTTOM;	}

  Fl_Color border_color(void) const				//	Get border colors
  	{	return vborder_color;	}
  Fl_Color border_color(Fl_Color n);			//	Set border colors
  void clear_border_color(void);					//	Undefine border color
  bool border_color_defined(void) const;	//	Is border color defined?

  int border_spacing(void) const					//	Get border spacings
  	{	return vborder_spacing;	}
  int border_spacing(int n);							//	Set border spacings
  void clear_border_spacing(void);				//	Undefine border spacing
  bool border_spacing_defined(void) const;	//	Is border spacing defined?

	Fl_Widget *editor(void) const						//	Get content editor
		{	return veditor;	};
	Fl_Widget *editor(Fl_Widget *v);
	void clear_editor(void);								//	Undefine content editor
	bool editor_defined(void) const;				//	Is content editor defined?

	const Fl_Font &font(void) const					//	Get current font
		{	return vfont;	};
	const Fl_Font &font(const Fl_Font &n);	//	Set current font
	void clear_font(void);									//	Undefine font
	bool font_defined(void) const;					//	Is font defined

	int font_size(void)	const								//	Get font size
		{	return vfont_size;	};
	int font_size(int n);										//	Set font size
	void clear_font_size(void);							//	Undefine font size
	bool font_size_defined(void) const;			//	Is font size defined?

	Fl_Color foreground(void) const					//	Get foreground color
		{	return vforeground;	};
	Fl_Color foreground(Fl_Color n);				//	Set foreground color
	void clear_foreground(void);						//	Undefine foreground color
	bool foreground_defined(void) const;		//	Is foreground defined?

	const Fl_Boxtype &frame(void) const			//	Get frame type
		{	return vframe;	};
	const Fl_Boxtype &frame(const Fl_Boxtype &n) ;	//	Set frame type
	void clear_frame(void);									//	Undefine frame type
	bool frame_defined(void) const;					//	Is frame type defined?

	int height(void) const									//	Get height
		{	return vheight;	};
	int height(int n );											//	Set height
	void clear_height(void);								//	Undefine row height
	bool height_defined(void) const;				//	Is row height defined


	bool locked(void) const									//	Get locked
		{	return vlocked;	}
	bool locked(bool n);										//	Set locked
	void clear_locked(void);								//	Undefine locked
	bool locked_defined(void) const;				//	Is locked defined?

	bool resizable(void) const							//	Get resizable (Not for Cell)
		{	return vresizable;	};
	bool resizable(bool n);									//	Set resizable
	void clear_resizable(void);							//	Undefine resizable
	bool resizable_defined(void) const;			//	Is resizable defined?

	int width(void) const										//	Get column width
		{	return vwidth;	}
	int width(int n);												//	Set column width
	void clear_width(void);									//	Undefine column width
	bool width_defined(void) const;					//	Is column width defined?

  int x_margin(void) const								//	Get x margin
  	{	return vx_margin;	}
  int x_margin(int x);										//	Set x margin
  void clear_x_margin(void);							//	Undefine x margin
  bool x_margin_defined(void) const;			//	Is x margin defined?

	int y_margin(void) const								//	Get y margin
  	{	return vy_margin;	}
  int y_margin(int y);										//	Set y margin
  void clear_y_margin(void);							//	Undefine y margin
  bool y_margin_defined(void) const;			//	Is y margin defined?

	//	Cumulative assignment operator
	//	This will only assign portions that are defined.
	const Flv_Style &operator=(const Flv_Style &n);

	Flv_Style_List cell_style;

protected:
	int value(void) const										//	Get row/column #
		{	return vvalue;	};
	int value(int n)												//	Set row/column #
		{	return (vvalue=n);	}

private:
	unsigned int vdefined;									//	Which parts are defined?
	Fl_Align valign;												//	Drawing alignment
	Fl_Color vbackground;										//	Background color
  unsigned char vborder;									//	Borders around cell
  unsigned char vborder_spacing;					//	Spacing between inner/outer border
	Fl_Color vborder_color;									//	Outer border color
	Fl_Widget *veditor;											//	Content editor
	unsigned char vx_margin;								//	X margin (Left/Right)
	unsigned char vy_margin;								//	Y margin (Top/Bottom)
	Flv_Style_List vcell;										//	Cell list
	Fl_Font vfont;													//	Font to draw with
	int vfont_size;													//	Size of font
	Fl_Color vforeground;										//	Foreground color
	Fl_Boxtype vframe;											//	Frame around cell
	int vheight;														//	Row height
	bool vlocked;														//	Group locked?
	bool vresizable;												//	Allow resizing?
	int vvalue;															//	Row or Column #
	int vwidth;															//	Column height
};
#endif


--- NEW FILE: iostream.H ---
// $Id: iostream.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $

#ifndef _STREAMIO_HH_
#define _STREAMIO_HH_

// Miscellaneous functions for operating on IO streams in C++

#include <iostream.h>
#include <iomanip.h>

inline void remove_white_space(istream& i) {
  char c;

  while ( i )
     {
       i.get(c);
       if ( c != ' ' && c != '\t' && c != '\n' )
          {
            i.putback(c);
            break;
          }
     }
}

inline void remove_spaces(istream& i)
{
  char c;

  while ( i )
     {
       i.get(c);
       if ( c != ' ' )
          {
            i.putback(c);
            break;
          }
     }
}

inline void remove_spaces_and_tabs(istream& i)
{
  char c;

  while ( i )
     {
       i.get(c);
       if ( c != ' ' && c != '\t' )
          {
            i.putback(c);
            break;
          }
     }
}

inline void read_till_eol(istream& i)
{
  char c;

  i.get(c);
  while ( i && c != '\n' )
     i.get(c);
}

#endif // #ifndef _STREAMIO_HH_


--- NEW FILE: FXml.H ---
/* -*-C++-*- 

   "$Id: FXml.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FXML_H__
#define _FXML_H__

#include <libxml/parser.h>

/**
 * @package libflek_xml
 */

typedef enum {
  FXmlElementNode = XML_ELEMENT_NODE,
  FXmlAttributeNode = XML_ATTRIBUTE_NODE,
  FXmlTextNode = XML_TEXT_NODE,
  FXmlCDataSectionNode = XML_CDATA_SECTION_NODE,
  FXmlEntityRefNode = XML_ENTITY_REF_NODE,
  FXmlEntityNode = XML_ENTITY_NODE,
  FXmlPiNode = XML_PI_NODE,
  FXmlCommentNode = XML_COMMENT_NODE,
  FXmlDocumentNode = XML_DOCUMENT_NODE,
  FXmlDocumentTypeNode = XML_DOCUMENT_TYPE_NODE,
  FXmlDocumentFragNode = XML_DOCUMENT_FRAG_NODE,
  FXmlNotationNode = XML_NOTATION_NODE,
  FXmlHtmlDocumentNode = XML_HTML_DOCUMENT_NODE,
  FXmlDtdNode = XML_DTD_NODE,
  FXmlElementDecl = XML_ELEMENT_DECL,
  FXmlAttributeDecl = XML_ATTRIBUTE_DECL,
  FXmlEntityDecl = XML_ENTITY_DECL
} FXmlElementType;

typedef enum {
  FXmlAttributeCData = XML_ATTRIBUTE_CDATA,
  FXmlAttributeId = XML_ATTRIBUTE_ID,
  FXmlAttributeIdRef = XML_ATTRIBUTE_IDREF,
  FXmlAttributeIdRefs = XML_ATTRIBUTE_IDREFS,
  FXmlAttributeEntity = XML_ATTRIBUTE_ENTITY,
  FXmlAttributeEntities = XML_ATTRIBUTE_ENTITIES,
  FXmlAttributeNMToken = XML_ATTRIBUTE_NMTOKEN,
  FXmlAttributeNMTokens = XML_ATTRIBUTE_NMTOKENS,
  FXmlAttributeEnumeration = XML_ATTRIBUTE_ENUMERATION,
  FXmlAttributeNotation = XML_ATTRIBUTE_NOTATION
} FXmlAttributeType;

typedef enum {
  FXmlAttributeNone = XML_ATTRIBUTE_NONE,
  FXmlAttributeRequired = XML_ATTRIBUTE_REQUIRED,
  FXmlAttributeImplied = XML_ATTRIBUTE_IMPLIED,
  FXmlAttributeFixed = XML_ATTRIBUTE_FIXED
} FXmlAttributeDefault;

class FXmlDocument;
class FXmlNode;

/**
 * Attribute
 */
class FXmlAttr {

 public:

  FXmlAttr () { Attr = 0; }
  FXmlAttr (xmlAttrPtr);
  bool valid () { if (Attr) return true; return false; }
  FXmlElementType type ();

  const char* name ();  
  FXmlNode children ();
  FXmlAttr next ();
  FXmlAttr previous ();
  FXmlNode parent ();
  FXmlNode last ();
  FXmlDocument document ();

  FXmlAttributeType atype ();
  //FXmlAttrDefault def ();
  //const char* defaultValue ();

  FXmlNode value ();

 protected:

  xmlAttrPtr Attr;

};

/**
 * Node.
 */
class FXmlNode {

 public:

  FXmlNode () { Node = 0; }
  FXmlNode (xmlNodePtr);
  bool valid () { if (Node) return true; return false; }
  FXmlElementType type ();

  const char* name ();  
  FXmlNode children ();
  FXmlNode next ();
  FXmlNode previous ();
  FXmlNode parent ();
  FXmlNode last ();
  FXmlDocument document ();
  // FXmlNs ns ();
  char* content ();  

  FXmlAttr properties ();
  char* property (const char* name);

  FXmlNode& operator = (const xmlNodePtr& p)
    {
      Node = p;
      return (*this);
    }

  FXmlNode& operator = (const FXmlNode& p)
    {
      Node = p.Node;
      return (*this);
    }
  
 protected:

  xmlNodePtr Node;

};

/**
 * Document
 */
class FXmlDocument {

 public:

  FXmlDocument () { Doc = 0; }
  FXmlDocument (xmlDocPtr);
  bool valid () { if (Doc) return true; return false; }
  FXmlElementType type ();

  const char* name ();
  FXmlNode children ();
  FXmlNode next ();
  FXmlNode previous ();
  FXmlNode parent ();
  FXmlNode last ();
  FXmlDocument document ();

  // Basic parsing interface:
  static FXmlDocument parse_file (const char* filename);
  static FXmlDocument parse_buffer (const char* buffer, int size);

 protected:

  xmlDocPtr Doc;

};

#endif

--- NEW FILE: FMatrix3x3.H ---
/* -*-C++-*- 

   "$Id: FMatrix3x3.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FMATRIX3x3_H_
#define _FMATRIX3x3_H_

#include <Flek/FBase.H>
#include <Flek/FVector3.H>

/** @package libflek_core
 * Class for a 3x3 matrix. Built from Vector3d
 * Row-major form is used. (ie) each row of the matrix
 * is a Vector3d. This makes inversion easier, since elementary
 * row operations are simplified
 */

class FMatrix3x3 : public FBase
{
public:
  
  typedef FMatrix3x3 * Ptr;
  
  /**
   * Default constructor - creates an identity matrix.
   */
  FMatrix3x3 ()
    : FBase ()
    {
      row[0].set (1.0, 0.0, 0.0);
      row[1].set (0.0, 1.0, 0.0);
      row[2].set (0.0, 0.0, 1.0);
    }

  /**
   * One argument constructor - from scalar, set all elements to given value.
   */
  FMatrix3x3 (double scalar)
    : FBase ()
    {
      row[0] = scalar; row[1] = scalar; row[2] = scalar;
    }
  
  /**
   * Three argument constructor - from 3 FVector3s.
   */
  FMatrix3x3 (const FVector3& r0, const FVector3& r1, const FVector3& r2)
    : FBase ()
    {
      row[0] = r0; row[1] = r1; row[2] = r2;
    }

  /**
   * Copy constructor.
   */
  FMatrix3x3 (const FMatrix3x3& mat)
    : FBase ()
    {
      copy_from (mat);
    }

  /**
   * Destructor
   */
  virtual ~FMatrix3x3 ()
    {}
  
  /**
   *  Assignment operator
   */
  FMatrix3x3& operator = (const FMatrix3x3& mat)
    {
      copy_from (mat);
      return (*this);
    }
  
  /**
   * Assignment from a scalar
   */
  void operator = (double scalar)
    {
      row[0] = scalar; row[1] = scalar; row[2] = scalar;
    }
  
  /**
   * Sets the rows of the matrix.
   * 
   * @param r0 The new row "0" for this matrix.
   * @param r1 The new row "0" for this matrix.
   * @param r2 The new row "0" for this matrix.
   */
  void set(const FVector3& r0, const FVector3& r1, const FVector3& r2)
    {
      row[0] = r0; row[1] = r1; row[2] = r2;
    }

  /**
   * Sets every element in the matrix to a scalar.
   * 
   * @param scalar Value assigned to each element.
   */
  void set (double scalar)
    {
      row[0] = scalar; row[1] = scalar; row[2] = scalar;
    }
     
  /**
   *  Reset the matrix to it's default state - identity
   */
  void reset ()
    {
      row[0].set (1.0, 0.0, 0.0);
      row[1].set (0.0, 1.0, 0.0);
      row[2].set (0.0, 0.0, 1.0);
    }

  /*
   * Make a copy of the object
   * implement FBase class pure virtual function
   */
  virtual FBase::Ptr copy (void) const
    {
      Ptr mat = new FMatrix3x3 (*this);
      return mat;
    }

  /**
   * Access a row of the matrix - no range checks
   * 
   * @param index The index of the row that should be returned.
   * @return The specified row of the matrix.
   */
  FVector3& operator [] (uint index) {
    return row[index];
  }

  /**
   * Access a row of the matrix - no range checks : const version
   * 
   * @param index The index of the row that should be returned.
   * @return The specified row of the matrix.
   */
  const FVector3& operator [] (uint index) const
    {
      return row[index];
    }

  /**
   * Creates the identity matrix.
   * 
   * @return The identity matrix.
   */
  static FMatrix3x3 identity ()
    {
      FMatrix3x3 imat;  // Default constructor creates an identity matrix
      return imat;
    }

  /**
   * Creates the identity matrix.
   * 
   * @return The identity matrix.
   */
  static FMatrix3x3 I (void)
    {
      FMatrix3x3 imat;  // Default constructor creates an identity matrix
      return imat;
    }
  
  /**  
   * Adds each element in the given matrix to this matrix.
   * 
   * @param mat The matrix of values to add to this matrix.
   */
  void operator += (const FMatrix3x3& mat)
    {
      for (int i=0; i < 3; ++i)
	row[i] += mat.row[i];
    }

  /**  
   * Subtracts each element in the given matrix from this matrix.
   * 
   * @param mat The matrix of values to subtract from this matrix.
   */
  void operator -= (const FMatrix3x3& mat)
    {
      for (int i=0; i < 3; ++i)
	row[i] -= mat.row[i];
    }

  /**  
   * Multiplies each element in the matrix by a scalar.
   * 
   * @param scalar The scalar to multiply by.
   */
  void operator *= (double scalar)
    {
      for (int i=0; i < 3; ++i)
	row[i] *= scalar;
    }

  /**  
   * Divides each element in the matrix by a scalar.
   * 
   * @param scalar The scalar to divide by.
   */
  void operator /= (double scalar)
    {
      for (int i=0; i < 3; ++i)
	row[i] /= scalar;
    }
  
  /**
   * Transposes this matrix.
   */
  void transpose (void)
    {
      for (int i=0; i < 3; ++i)
	for (int j=i+1; j < 3; ++j)
	  swap (row[i][j], row[j][i]);
    }

  /**
   * Finds the transpose of a given matrix.
   * 
   * @param mat The matrix to find a transpose for.
   * @return The transpose of the giben matrix.
   */
  friend FMatrix3x3 transpose (const FMatrix3x3& mat)
    {
      FMatrix3x3 trans (mat); trans.transpose ();
      return trans;
    }

  /**
   * Finds the determinant of a given matrix.
   * 
   * @param mat The source matrix.
   * @return The detrminant of the source matrix.
   */  
  friend double determinant(const FMatrix3x3& mat)
    {
      double det = 0.0;
      
      det =   mat[0][0] * mat[1][1] * mat[2][2] 
	+ mat[0][1] * mat[1][2] * mat[2][0] 
	+ mat[0][2] * mat[1][0] * mat[2][1] 
	- mat[2][0] * mat[1][1] * mat[0][2] 
	- mat[2][1] * mat[1][2] * mat[0][0] 
	- mat[2][2] * mat[1][0] * mat[0][1];
      return det;
    }
  
  /**
   * Inverts this matrix, using elementary row operations.
   */
  void invert (void)
    {
      FVector3 inv[3];
      int i,j,swaprow;
     
      for (i=0; i<3; ++i)
	inv[i][i] = 1.0;
      
      // inv will be identity initially and will become the inverse at the end
      for (i=0; i < 3; ++i)
	{
	  // i is column
	  // Find row in this column which has largest element (magnitude)
	  swaprow = i;
	  for (j=i+1; j < 3; ++j)
	    if ( fabs (row[j][i]) > fabs (row[i][i]) ) swaprow = j;
	  
	  if ( swaprow != i )
	    {
	      // Swap the two rows to get largest element in main diagonal
	      // Do this for the RHS also
	      swap (row[i],row[swaprow]); 
	      swap (inv[i],inv[swaprow]);
	    }
	  
	  // Check if pivot is non-zero
	  if ( !is_non_zero(row[i][i]) )
	    {
	      cerr << "FMatrix3x3 inverse(const FMatrix3x3&) : Singular matrix!" << endl;
	      // Return original matrix without change
	      return;
	    }
	  
	  // Divide matrix by main diagonal element to make it 1.0
	  double fact = row[i][i];
	  for (j=0; j < 3; ++j)
	    {
	      row[j] /= fact;
	      inv[j] /= fact;
	    }
	  
	  // Make non-main-diagonal elements in this column 0 using main-diagonal row
	  for (j=0; j < 3; ++j)
	    {
	      if ( j != i )
		{
		  double temp = row[j][i];
		  row[j] -= row[i]*temp;
		  inv[j] -= inv[i]*temp;
		}
	    }
	}
      
      // Main-diagonal elements on LHS may not be 1.0 now. Divide to make LHS identity
      // Last row will be 1.0
      for (i=0; i < 2; ++i)
	{
	  double pivot = row[i][i];
	  row[i] /= pivot;
	  inv[i] /= pivot;
	}
      for (i=0; i < 3; ++i)
	row[i] = inv[i];
    }
  
  /**
   * Find the inverse of a given matrix using elementary row operations.
   * 
   * @param mat The source matrix.
   * @return The inverse of the source matrix.
   */
  friend FMatrix3x3 invert (const FMatrix3x3& mat)
    {
      FMatrix3x3 inv (mat); inv.invert ();
      return inv;
    }
  
  /**
   * Negation.  Each element in the given matrix is returned
   * negated in a new matrix.
   * 
   * @param mat The source matrix.
   * @return The negated matrix.
   */
  friend FMatrix3x3 operator - (const FMatrix3x3& mat)
    {
      FMatrix3x3 neg;
      
      for (int i=0; i < 3; ++i)
	neg.row[i] = -mat.row[i];
      
      return neg;
    }
  
  friend FMatrix3x3 operator + (const FMatrix3x3& mat1, const FMatrix3x3& mat2)
    {
      FMatrix3x3 sum (mat1);
      sum += mat2;
      return sum;
    }
  
  friend FMatrix3x3 operator - (const FMatrix3x3& mat1, const FMatrix3x3& mat2)
    {
      FMatrix3x3 diff (mat1);
      diff -= mat2;
      return diff;
    }
  
  /**
   * Post-multiplication by a scalar.
   */
  friend FMatrix3x3 operator * (const FMatrix3x3& mat, double scalar)
    {
      FMatrix3x3 prod (mat);
      prod *= scalar;
      return prod;
    }
  
  /**
   * Pre-multiplication by a scalar.
   */
  friend FMatrix3x3 operator * (double scalar, const FMatrix3x3& mat)
    {
      FMatrix3x3 prod (mat);
      prod *= scalar;
      return prod;
    }
  
  /**
   * Division by a scalar.
   */
  friend FMatrix3x3 operator / (const FMatrix3x3& mat, double scalar)
    {
      FMatrix3x3 quot (mat);
      quot /= scalar;
      return quot;
    }
  
  /**
   * Multiplication of 2 matrices - outer product.
   */
  friend FMatrix3x3 operator * (const FMatrix3x3& mat1, const FMatrix3x3& mat2);
  
  /** 
   * Element-by-element multiplication of 2 matrices.
   */
  friend FMatrix3x3 product (const FMatrix3x3& mat1, const FMatrix3x3& mat2)
    {
      FMatrix3x3 prod;
      
      prod.row[0] = product (mat1[0], mat2[0]);
      prod.row[1] = product (mat1[1], mat2[1]);
      prod.row[2] = product (mat1[2], mat2[2]);
      
      return prod;
    }
  
  /**
   * Post-multiplication by a FVector3. Vector is assumed to be a column vector.
   */
  friend FVector3 operator * (const FMatrix3x3& mat, const FVector3& vec)
    {
      FVector3 prod;
      
      prod.set (mat.row[0]*vec, mat.row[1]*vec, mat.row[2]*vec);
      return prod;
    }
  
  /**
   * Pre-multiplication by a FVector3. Vector is assumed to be a row vector.
   */
  friend FVector3 operator * (const FVector3& vec, const FMatrix3x3& mat);
  
  /** 
   * Multiplication of two FVector3s to produce a FMatrix3x3 - outer product
   * or tensor product of two Vectors.  Same as multiplying row vector (v1) 
   * with column vector (v2) 
   */
  friend FMatrix3x3 operator ^ (const FVector3& v1, const FVector3& v2)
    {
      FMatrix3x3 prod;
      
      prod.row[0] = v1[0]*v2;
      prod.row[1] = v1[1]*v2;
      prod.row[2] = v1[2]*v2;
      
      return prod;
    }
  
  friend void swap (FMatrix3x3& mat1, FMatrix3x3& mat2)
    {
      for (int i=0; i < 3; ++i)
	swap (mat1.row[i], mat2.row[i]);
    }
  
  /**
   * Multiply self with another matrix. Simply calls above defined 
   * friend function.
   */
  void operator *= (const FMatrix3x3& mat)
    {
      FMatrix3x3 prod = (*this) * mat;
      *this = prod;
    }
  
  friend ostream& operator << (ostream& o, const FMatrix3x3& mat)
    {
      o << "[ " << mat.row[0] << "," << endl
	<< "  " << mat.row[1] << "," << endl
	<< "  " << mat.row[2] << " ]" << endl;
      return o;
    }
  
  friend istream& operator >> (istream& i, FMatrix3x3& mat)
    {
      char rowsep, dummy;
      i >> dummy >> mat.row[0] >> rowsep
	>> mat.row[1] >> rowsep
	>> mat.row[2] >> dummy;
      return i;
    }
  
protected:
  
  /**
   * 3 rows of the matrix
   */
  FVector3 row[3];
  
  /**
   * Copy values from another matrix.
   */
  void copy_from (const FMatrix3x3& mat)
    {
      for (int i=0; i < 3; ++i)
	row[i] = mat.row[i];
    }
};

#endif // #ifndef FMatrix_3x3_H_ 

--- NEW FILE: FJPEG.H ---
/* -*-C++-*- 

   "$Id: FJPEG.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FJPEG_H_
#define _FJPEG_H_

#include <Flek/FImage.H>

/** @package libflek_jpeg
 * The FJPEG class provides static methods that read, write and test JPEG images.
 */
class FJPEG {
 public:

  /*
   * Check the PBM/PGM/PPM magic number to see if this image matches any of
   * the recognized formats.
   */
  //static bool valid (char *filename);

  /**
   * Read a JPEG from disk and return a new fImage object.
   */
  static FImage * read (char *filename);

  /**
   * Write a JPEG to disk from an fImage object.
   */  
  static int write (char *filename, FImage* img, int qaulity);

};

#endif

--- NEW FILE: export.h ---
/*
 The following is only used when building DLLs under WIN32
*/

/* CET - FIXME - class definitions in headers still need to be fixed */

#if defined(WIN32) && defined(FLEK_SHARED)
#  ifdef FLEK_LIBRARY
#    define FLEK_API            __declspec(dllexport)
#  else
#    define FLEK_API            __declspec(dllimport)
#  endif
#  ifdef FLEK_UI_LIBRARY
#    define FLEK_UI_API         __declspec(dllexport)
#  else
#    define FLEK_UI_API         __declspec(dllimport)
#  endif
#  ifdef FLEK_GL_LIBRARY
#    define FLEK_GL_API         __declspec(dllexport)
#  else
#    define FLEK_GL_API         __declspec(dllimport)
#  endif
#  ifdef FLEK_XML_LIBRARY
#    define FLEK_XML_API        __declspec(dllexport)
#  else
#    define FLEK_XML_API        __declspec(dllimport)
#  endif
#  ifdef FLEK_JPEG_LIBRARY
#    define FLEK_JPEG_API       __declspec(dllexport)
#  else
#    define FLEK_JPEG_API       __declspec(dllimport)
#  endif
#else
#  define FLEK_API
#  define FLEK_UI_API
#  define FLEK_GL_API
#  define FLEK_XML_API
#  define FLEK_JPEG_API
#endif

--- NEW FILE: FVector4.H ---
/* -*-C++-*-
 
   "$Id: FVector4.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FVECTOR4_H_
#define _FVECTOR4_H_

#include <Flek/FVector.H>

/** @package libflek_core
 * FVector4 is a 4 dimensional vector represented internally as an array of 
 * doubles.  This class is related to FVector2 and FVector3 which are 
 * 2-D and 3-D versions of this class.  All FVector classes are forward
 * declared in FVector.h.
 */
class FVector4 : public FBase
{

public:

  typedef FVector4* Ptr;
  
  /**
   * The default constructor sets each element in the vector to 0.
   */
  FVector4 ()
    : FBase ()
    {
      elem[0] = elem[1] = elem[2] = elem[3] = 0.0;
    }
  
  /**
   * This one argument constructor intializes all elements in the vector
   * with the given value.
   */
  FVector4 (double val)
    : FBase ()
    {
      elem[0] = elem[1] = elem[2] = elem[3] = val;
    }
  
  /**
   * This one argument constructor initializes the vector with the first
   * three elements in the given array.
   */
  FVector4 (double * arr)
    : FBase ()
    {
      elem[0] = arr[0]; elem[1] = arr[1]; elem[2] = arr[2]; elem[3] = arr[3];
    }
  
  /**
   * This four argument constructor initializes the vector with the
   * passed values.
   */
  FVector4 (double val1, double val2, double val3, double val4)
    : FBase ()
    {
      elem[0] = val1; elem[1] = val2; elem[2] = val3; elem[3] = val4;
    }
  
  /**
   * The copy constructor initializes this vector with the contents 
   * of another vector.
   */
  FVector4 (const FVector4& vec)
    : FBase (vec)
    {
      elem[0] = vec.elem[0]; elem[1] = vec.elem[1];
      elem[2] = vec.elem[2]; elem[3] = vec.elem[3];
    }
  
  /**
   * This constructor initializes the vector from the contents of a
   * FVector2 (a 2D vector).  The third and forth elements are set to zero.
   */
  FVector4 (const FVector2& vec)
    : FBase ()
    {
      copy_from (vec);
    }
  
  /**
   * This constructor initializes the vector from the contents of a
   * FVector2 (a 2D vector).  The third element is set to zero.
   */
  FVector4 (const FVector3& vec)
    : FBase ()
    {
      copy_from (vec);
    }
  
  /**
   * The virtual destructor does nothing.
   */
  virtual ~FVector4 ()
    {}

  /**
   * Assignment operator from another FVector3.
   */
  FVector4& operator = (const FVector4& vec)
    {
      elem[0] = vec.elem[0]; elem[1] = vec.elem[1];
      elem[2] = vec.elem[2]; elem[3] = vec.elem[3];
      return (*this);
    }
  
  /** 
   * Assignment operator from a scalar.  All elements are set to 
   * the scalar value.
   */
  FVector4& operator = (double scalar)
    {
      elem[0] = elem[1] = elem[2] = elem[3] = scalar;
      return (*this);
    }
  
  /** 
   * Assignment operator from a FVector2.  The third and forth elements 
   * are set to 0.
   */
  FVector4& operator = (const FVector2& vec)
    {
      copy_from (vec);
      return (*this);
    }
  
  /** 
   * Assignment operator from a FVector3.  The forth element is set to 0.
   */
  FVector4& operator = (const FVector3& vec)
    {
      copy_from (vec);
      return (*this);
    }
  
  /**
   * Make a copy of the object.
   */
  virtual FBase::Ptr copy (void) const
    {
      Ptr vec = new FVector4 (*this);
      return vec;
    }
  
  /** 
   * Set each element vector to the given values.
   */
  void set (double v1, double v2, double v3, double v4)
    {
      elem[0] = v1; elem[1] = v2; elem[2] = v3; elem[3] = v4;
    }
  
  /** 
   * Set each element vector to the given value.
   */
  void set (double val)
    {
      elem[0] = elem[1] = elem[2] = elem[3] = val;
    }
  
  /** 
   * Set elements of vector to default values.
   */
  void reset (void)
    {
      set (0.0);
    }
  
  /** 
   * Get the elements of vector into given values.
   */
  void get (double& v1, double& v2, double& v3, double& v4) const
    {
      v1 = elem[0]; v2 = elem[1]; v3 = elem[2]; v4 = elem[3];
    }
  
  /**
   * Fill an array with the elements of the vector.
   */
  void fill_array (double arr[4]) const
    {
      arr[0] = elem[0]; arr[1] = elem[1]; arr[2] = elem[2]; arr[3] = elem[3];
    }
  
  /** 
   * Element access operator.  For efficiency, this doesn't check for 
   * valid indices
   */
  double& operator [] (uint index)
    {
      return elem[index];
    }
  
  /** 
   * Element access operator.  For efficiency, this doesn't check for 
   * valid indices
   */
  double operator [] (uint index) const
    {
      return elem[index];
    }
  
  /**
   * Arithmetic operator for additive assignment.
   */
  void operator += (const FVector4& vec)
    {
      elem[0] += vec.elem[0]; elem[1] += vec.elem[1];
      elem[2] += vec.elem[2]; elem[2] += vec.elem[2];
    }
  
  /**
   * Arithmetic operator for subtractive assignment.
   */
  void operator -= (const FVector4& vec)
    {
      elem[0] -= vec.elem[0]; elem[1] -= vec.elem[1];
      elem[2] -= vec.elem[2]; elem[3] -= vec.elem[3];
    }
  
  /**
   * Arithmetic operator for multiplicative (scalar) assignment.
   */
  void operator *= (double scalar)
    {
      elem[0] *= scalar; elem[1] *= scalar; elem[2] *= scalar; elem[3] *= scalar;
    }
  
  /**
   * Arithmetic operator for divisive (scalar) assignment.
   */
  void operator /= (double scalar)
    {
      elem[0] /= scalar; elem[1] /= scalar; elem[2] /= scalar; elem[3] /= scalar;
    }
  
  /**
   * Arithmetic operator for addition.
   */      
  FVector4 operator + (const FVector4& vec) const
    {
      FVector4 sum(*this);
      sum += vec;
      return sum;
    }
  
  /**
   * Arithmetic operator for subtraction.
   */ 
  FVector4 operator - (const FVector4& vec) const
    {
      FVector4 diff(*this);
      diff -= vec;
      return diff;
    }
  
  /**
   * Operator for scalar multiplication (dot product).
   */
  double operator * (const FVector4& vec) const
    {
      double dotprod = elem[0]*vec.elem[0] + elem[1]*vec.elem[1]
	+ elem[2]*vec.elem[2] + elem[3]*vec.elem[3];
      return dotprod;
    }
  
  /**
   * Friend operator for negation.
   */
  friend FVector4 operator - (const FVector4& vec)
    {
      FVector4 negv (-vec.elem[0], -vec.elem[1], -vec.elem[2], -vec.elem[3]);
      return negv;
    }
  
  /**
   * Friend operator for scalar pre-multiplication.
   */
  friend FVector4 operator * (double scalar, const FVector4& vec)
    {
      FVector4 prod (vec);
      
      prod *= scalar;
      return prod;
    }
  
  /**
   * Friend operator for scalar post-multiplication.
   */  
  friend FVector4 operator * (const FVector4& vec, double scalar)
    {
      FVector4 prod (vec);
      
      prod *= scalar;
      return prod;
    }
  
  /**
   * Friend operator for scalar division.
   */
  friend FVector4 operator / (const FVector4& vec, double scalar)
    {
      FVector4 prod (vec);
      
      prod /= scalar;
      return prod;
    }
  
  /**
   * Friend operator for element-by-element product.
   */
  friend FVector4 product(const FVector4& vec1, const FVector4& vec2)
    {
      FVector4 prod (vec1[0]*vec2[0], vec1[1]*vec2[1], vec1[2]*vec2[2], vec1[3]*vec2[3]);
      
      return prod;
    }
  
  /**
   * Boolean equality operator.
   */     
  bool operator == (const FVector4& vec) const
    {
      if ( (fabs(elem[0]-vec.elem[0]) > ZERO) ||
	   (fabs(elem[1]-vec.elem[1]) > ZERO) ||
	   (fabs(elem[2]-vec.elem[2]) > ZERO) ||
	   (fabs(elem[3]-vec.elem[3]) > ZERO) )
	return false;
      return true;
    }
  
  /**
   * Boolean ineqality operator.
   */
  bool operator != (const FVector4& vec) const
    {
      return !( (*this) == vec );
    }
  
  // Other functions
  
  /**
   * Square of the norm of the vector.
   */     
  friend double normsqr (const FVector4& vec)
    {
      double nsq = sqr (vec.elem[0]) + sqr (vec.elem[1]) + sqr (vec.elem[2]) + sqr (vec.elem[3]);
      return nsq;
    }
  
  /**
   * Norm of the vector.
   */
  friend double norm (const FVector4& vec)
    {
      return sqrt (normsqr (vec));
    }

  /** 
   * Length (norm) of the vector.
   */
  double length ()
    {
      return norm (*this);
    }

  /**
   * Normalize.  Returns previous norm.
   */
  friend double normalize(FVector4& vec)
    {
      double n = norm(vec);
      if ( is_non_zero (n) == true ) vec /= n;
      return n;
    }
  
  /** 
   * Returns normalized vector.
   */
  friend FVector4 normalized (const FVector4& vec)
    {
      FVector4 nvec (vec);
      normalize (nvec);
      return nvec;
    }
  
  /**
   * Swap the elements of two FVector4s.
   */     
  friend void swap(FVector4& vec1, FVector4& vec2)
    {
      swap (vec1.elem[0], vec2.elem[0]);
      swap (vec1.elem[1], vec2.elem[1]);
      swap (vec1.elem[2], vec2.elem[2]);
      swap (vec1.elem[3], vec2.elem[3]);
    }
  
  /**
   * I/O Stream extraction operator.  Of the form "[ x y z ]". 
   */ 
  friend istream& operator >> (istream& i, FVector4& vec)
    {
      remove_white_space(i);
      if ( i.peek() == '[' )
	{
	  // Correct format
	  int numread = 0;  // No. of elements read
	  double val;
	  char c;
	  
	  i >> c;  // Read opening square bracket
	  while ( numread < 4 )
	    {
	      i >> val; vec.elem[numread] = val;
	      numread++;
	    }
	  
	  // Read all characters till closing bracket is found
	  // If no. of chars read is more than 10 then print an error
	  // message and exit;
	  i >> c;
	  numread = 1;
	  while ( c != ']' && numread < 10 )
	    {
	      i >> c; numread++;
	    }
	  
	  if ( numread >= 10 )
	    {
	      cerr << "operator >> FVector4 : Incorrect format. Closing ']' not"
		   << " found upto 10 characters after 4th element of vector"
		   << endl;
	      exit(0);
	    }
	}
      
      return i;
    }
  
  /**
   * I/O Stream insertion operator.  Of the form "[ x y z ]". 
   */ 
  friend ostream& operator << (ostream& o, const FVector4& vec)
    {
      // User can set precision from 0 to 6
      o << setiosflags (ios::fixed) << setiosflags (ios::showpoint);
      
      int oldprec = o.precision ();
      if ( oldprec < 0 ) o << setprecision(0);
      if ( oldprec > 6 ) o << setprecision(6);
      
      o << "["
	<< vec.elem[0] << " "
	<< vec.elem[1] << " "
	<< vec.elem[2] << " "
	<< vec.elem[3]
	<< "]";
      
      o << setprecision (oldprec);
      return o;
    }

protected:
  
  double elem[4];
  
  /**
   * Initialize the elements from a FVector2,
   */
  void copy_from (const FVector2& vec);
  
  /**
   * Initialize the elements from a FVector4,
   */
  void copy_from (const FVector3& vec);
  
};

#endif // #ifndef FVector_4_H


--- NEW FILE: Fl_Toggle_Tree_Base.H ---
/* -*-C++-*- 

   "$Id: Fl_Toggle_Tree_Base.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FL_TREE_H_
#define _FL_TREE_H_

#include <FL/fl_draw.H>
#include <FL/Fl_Scroll.H>

#include <Flek/Fl_Toggle_Node_Base.H>

#define FL_DAMAGE_TREE 0x40

enum sort_order {
  NORMAL_SORT = 0,
  REVERSE_SORT = 1
};

/** @package libflek_ui
 * This is the base class for Fl_Toggle_Tree. It could conceivably be 
 * used to create other tree-like widgets. 
 *
 * This class has been designed to maintain a doubly linked tree list, 
 * and defers data storage and management to subclasses of 
 * Fl_Toggle_Tree_Base and Fl_Toggle_Node_Base. This class also maintains 
 * wether it's branches are visible or not (i.e. "opened" or "closed"). 
 */
class Fl_Toggle_Tree_Base : public Fl_Widget 
{
public:

  /**
   * The constructor makes an empty Fl_Toggle_Tree_Base. 
   */
  Fl_Toggle_Tree_Base (int x, int y, int w, int h);

  /**
   * Returns the first (top) Fl_Toggle_Node_Base in the widget tree.
   */
  Fl_Toggle_Node_Base* first(void) {
    return first_;
  }

  Fl_Toggle_Node_Base* find(int fy, int& depth, int& ry);

  /**
   * Sets the current pointer to t.
   */
  void traverse_start(Fl_Toggle_Node_Base * a);

  /**
   * Sets the traversal pointer to first() and then
   * returns first().
   */
  Fl_Toggle_Node_Base * traverse_start();

  /**
   * If the current node has an up pointer, traverse_up returns 
   * this pointer and sets it as the current node. 
   */
  void traverse_up (void);

  /**
   * This method traverses forward through the tree. Traversal through 
   * the node tree is done by a depth first traversal that updates the 
   * current node pointer. If traverse_forward returns 0, then the 
   * current node pointer has reached the end of the tree. Otherwise, 
   * traverse_forward returns the next node in the tree. 
   *
   * The visible flag should be set to 1 if you want to restrict 
   * traversal to the visible tree (the Fl_Toggle_Node_Bases that are 
   * not closed). The depth variable is updated with the new node depth,
   * if the old node depth is passed to traverse_forward. 
   */
  Fl_Toggle_Node_Base * traverse_forward(int visible, int &depth);

  /**
   * Equivalent to traverse_forward (0, temp). 
   */
  Fl_Toggle_Node_Base * traverse_forward();

  /**
   * Traverse back one.
   */
  Fl_Toggle_Node_Base * traverse_backward();

  /**
   * Insert n as the next item after current node. 
   */
  void add_next (Fl_Toggle_Node_Base* node);

  /**
   * Insert n as the next sub item after the current node. 
   */
  void add_sub (Fl_Toggle_Node_Base* node);

  /**
   * Remove n (and all of it's sub nodes) from the tree. If 
   * successful returns 1, else returns 0. 
   */
  int remove (Fl_Toggle_Node_Base * a);

  /** 
   * Clear the tree. 
   */
  int clear();

  /**
   * Virtual method that draws the tree. 
   */
  virtual void draw(void);

  /**
   * Update the height of the tree. 
   */
  void update_height(void);

  /**
   * Set node n as "open". 
   */
  int open(Fl_Toggle_Node_Base* node);

  /**
   * Set node n as "closed".
   */
  int close(Fl_Toggle_Node_Base* node);

  /**
   * Return the top most node in the tree.
   */
  Fl_Toggle_Node_Base* top() {
    return top_;
  }
protected:

  Fl_Toggle_Node_Base* first_;
  Fl_Toggle_Node_Base* top_;
  Fl_Toggle_Node_Base* t_current_;
  Fl_Toggle_Node_Base* current_;

  int top_depth_;
  int top_yoffset_;

  Fl_Toggle_Node_Base* damaged_;

  virtual int height(Fl_Toggle_Node_Base* node);
  int height_(Fl_Toggle_Node_Base* node) {
    return height(node) | 1;
    // height must be |1 , so Fl_ToggleTree can do color-swapping
    // with &1 on y coordinate
  }
  int total_height(Fl_Toggle_Node_Base* node);
  void update_top(void);
  virtual void draw_node(int depth, int cy, Fl_Toggle_Node_Base* node);
  virtual int handle(int) { return 1; }

  Fl_Toggle_Node_Base* sort_( Fl_Toggle_Node_Base* start,
                  int (*compar)(Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
                  int down, sort_order order = NORMAL_SORT);

public:
  static int s_compare_(void* a, void *b);
  static int s_compare_reverse_(void* a, void *b);

  Fl_Toggle_Node_Base* sort(Fl_Toggle_Node_Base* start, int (*compar)(Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
                sort_order order = NORMAL_SORT);
  Fl_Toggle_Node_Base* sort_tree(Fl_Toggle_Node_Base* start, int (*compar)(Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
                     sort_order order = NORMAL_SORT);

  void sort(int (*compar)(Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
            sort_order order = NORMAL_SORT);
  void sort_tree(int (*compar)(Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
                 sort_order order = NORMAL_SORT);
};

#endif

--- NEW FILE: Fl_Toggle_Node.H ---
#ifndef _FL_TOGGLE_NODE_H_
#define _FL_TOGGLE_NODE_H_

#include <Flek/Fl_Toggle_Node_Base.H>
#include <string.h>

class Fl_Pixmap;

class Fl_Toggle_Node : public Fl_Toggle_Node_Base {

  friend class Fl_Toggle_Tree;

public:

  Fl_Toggle_Node(char* label = 0, int can_open = 1, Fl_Pixmap* pixmap = 0,
                void * d = 0) : Fl_Toggle_Node_Base() {
    vsub_ = 0;
    selected_ = 0;
    changed_ = 0;
    opened_ = 1;

    label_ = strdup(label);
    pixmap_ = pixmap;
    can_open_ = can_open;
    data_ = d;
  }

  char* label(void) {
    return label_;
  }

  void label(char* ptr) {
    if (label_)
      delete label_;
    label_ = strdup(ptr);
  }

  Fl_Pixmap* pixmap(void) {
    return pixmap_;
  }

  void pixmap(Fl_Pixmap* ptr) {
    pixmap_ = ptr;
  }

  void* user_data() const {
    return data_;
  }

  void user_data(void* v) {
    data_ = v;
  }

  int can_open() {
    return can_open_;
  }

  void can_open (int b) {
    can_open_ = b;
  }

  int is_open() {
    return opened_;
  }

  inline Fl_Toggle_Node* previous() { return (Fl_Toggle_Node*)prev_; }
  inline Fl_Toggle_Node* next() { return (Fl_Toggle_Node*)next_; }
  inline Fl_Toggle_Node* child() { return (Fl_Toggle_Node*)sub_; }
  inline Fl_Toggle_Node* visible_child() { return (Fl_Toggle_Node*)vsub_; }
  inline Fl_Toggle_Node* parent() { return (Fl_Toggle_Node*)up_; }

protected:

  int selected_;
  int changed_;
  int can_open_;

  char* label_;
  Fl_Pixmap* pixmap_;
  void* data_;

};

#endif

--- NEW FILE: FArcball_Control.H ---
/* -*-C++-*- 

   "$Id: FArcball_Control.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
  
   Please report all bugs and problems to "flek-devel at sourceforge.net".
   
*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FARCBALL_CONTROL_H_
#define _FARCBALL_CONTROL_H_

#include <Flek/FVector3.H>
#include <Flek/FQuaternion.H>
#include <Flek/FMatrix4x4.H>

enum AxisSet { CameraAxes=0, BodyAxes=1, NoAxes=2 };

/** 
 * @package libflek_gl
 * 
 * The FArcball_Control class provides a convenient 3d rotation Control.
 * This class is used by <a href="Fl_Gl_Arcball_Window.html">Fl_Gl_Arcball_Window</a>
 * to provide a user friendly rotation manipulator.
 */
class FArcball_Control
{
public:

  typedef FVector3 * Axes;
  
  /**
   * Default constructor.
   */
  FArcball_Control ();

  /**
   * Copy constructor.  This constructor copies the values from another
   * FArcball_Control.
   *
   * @param ab The FArcball_Control that this FArcball_Control should copy it's values from.
   */
  FArcball_Control (const FArcball_Control& ab);

  /**
   * Two argument constructor.  This constructor sets the initial center
   * and radius of the arcball.
   *
   * @param cen The center for all subsequent rotation operations.
   * @param radius The radius of the sphere used for determining where
   *   the user sweeps a rotation arc.  The radius is relative to the
   *   window, where the value 1.0 would be the size of the window.
   */
  FArcball_Control (const FVector3& cen, double rad);

  /**
   * The destructor.
   */
  ~FArcball_Control ();

  /**
   * The assignment operator.  This method assigns the values contained
   * in this arcball to that of another.
   *
   * @param ab The FArcball_Control that this FArcball_Control should copy it's values from.
   */
  FArcball_Control& operator = (const FArcball_Control& ab);
  
  /**
   * Sets the center of the arcball and it's radius.
   *
   * @param cen The center for all subsequent rotation operations.
   * @param radius The radius of the sphere used for determining where
   *   the user sweeps a rotation arc.  The radius is relative to the
   *   window, where the value 1.0 would be the size of the window.
   */
  void place (const FVector3& cen, double rad) {
    vCenter = cen; dRadius = rad;
  }

  /**
   * Sets the center of the arcball.
   *
   * @param cen The center for all subsequent rotation operations.
   */  
  void center (const FVector3& cen) {
    vCenter = cen;
  }

  /**
   * Sets the center of the arcball.
   *
   * @param x The x coordinate center for all subsequent rotation operations.
   * @param y The y coordinate center for all subsequent rotation operations.
   * @param z The z coordinate center for all subsequent rotation operations.
   */    
  void center (double x, double y, double z) {
    vCenter.set (x, y, z);
  }

  /**
   * Gets the center of the arcball.
   *
   * @return The center of the arcball.
   */    
  FVector3 center () const {
    return vCenter;
  }
  
  /**
   * Register an x-y mouse event.
   *
   * @param x The new x coordinate of the mouse.
   * @param y The new y coordinate of the mouse.
   */
  void mouse (double x, double y) {
    vNow.set (x, y, 0);
  }

  void reset () {
    qDown.reset(); qNow.reset(); mNow.reset();
  }

  /**
   * Update the arcball transformation matrix.
   */
  void update ();

  /**
   * Gets the arcball transformation matrix.
   *
   * @return The current arcball transforamtion matrix.
   */  
  FMatrix4x4 value () const {
    return mNow;
  }

  /**
   * Gets the rotation quaternion.
   *
   * @return The current arcball quaternion.
   */  
  FQuaternion quaternion_value () const {
    return qNow;
  }
  
  /**
   * Start dragging the mouse.
   */  
  void begin_drag () {
    bDragging = true; vDown = vNow;
  }

  /**
   * End dragging the mouse.
   */    
  void end_drag () {
    bDragging = false; qDown = qNow;
    sets[BodyAxes][0] = mNow[0];
    sets[BodyAxes][1] = mNow[1];
    sets[BodyAxes][2] = mNow[2];
  }
  
  /**
   * Gets wether or not we are currently dragging the mouse.
   *
   * @return True if we are dragging the mouse, else false.
   */
  bool dragging () const { return bDragging; }

  /**
   * Gets the current axis.
   * 
   * @return The current axis.  Possible values include CameraAxes, BodyAxes and NoAxes.
   */
  AxisSet axis () const { return asAxisSet; }

  /**
   * Sets the current axis.
   */
  void axis (AxisSet set) { // was use_set
    if ( !bDragging ) asAxisSet = set;
  }

  /**
   * Gets the axis index.
   *
   * @return The axis index.
   */
  int axis_index () const { return iAxisIndex; }

  Axes sets[2];

  /**
   * Gets the "from" point.
   *
   * @return The point on the arcball we are rotating from (initial click).
   */
  FVector3 & from () { return vFrom; }

  /**
   * Gets the "to" point.
   *
   * @return The point on the arcball we are rotating to.
   */
  FVector3 & to () { return vTo; }

  /**
   * Gets the arcball radius.
   *
   * @return The arcball radius relative to the size of the viewport.  
   *   Where 1.0 equals a diameter equal to the size of the viewport.
   */
  double radius () const { return dRadius; }

  /** 
   * Sets the arcball radius.
   *
   * @param The arcball radius.  Good values are usually less than 1.0.
   */
  void radius (const double r) { dRadius = r; }
  
 protected:
  FVector3 vCenter;
  double dRadius;

  FQuaternion qNow, qDown, qDrag;
  FVector3 vNow, vDown, vFrom, vTo;
  FMatrix4x4 mNow;
  bool bDragging;
  AxisSet asAxisSet;
  int iAxisIndex;
  
private:
  
  static FVector3 mouseOnSphere (const FVector3& mouse, const FVector3& ballCenter, double ballRadius);
  static FVector3 constrainToAxis (const FVector3& loose, const FVector3& axis);
  static int nearestConstraintAxis (const FVector3& loose, FVector3 * axes, int nAxes);
  static FQuaternion quatFromBallPoints (const FVector3& from, const FVector3& to);
  static void quatToBallPoints (const FQuaternion& q, FVector3& arcFrom, FVector3& arcTo);
    
};

#endif

--- NEW FILE: FTransformation.H ---
/* -*-C++-*- 

   "$Id: FTransformation.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FTRANSFORMATION_H_
#define _FTRANSFORMATION_H_

#include <Flek/FVector3.H>
#include <Flek/FMatrix4x4.H>
#include <Flek/FQuaternion.H>
#include <math.h>
#include <GL/gl.h>

/**
 * @package libflek_core
 *
 * Class for transformations (translation, scaling, rotation).
 */
class FTransformation {
  
public:

  typedef FTransformation* Ptr;
  
  /**
   * Default constructor.
   */
  FTransformation ()
    : transform() {}
  
  /**
   * Copy constructor.
   */
  FTransformation(const FTransformation& tr)
    : transform(tr.transform) {}
  
  /** 
   * Construct from a matrix
   */
  FTransformation (const FMatrix4x4& mat)
    : transform(mat) {}
  
  /**
   * Destructor.
   */
  ~FTransformation() {}
  
  /**
   * Assignment operator.
   */
  FTransformation& operator = (const FTransformation& tr) {
    transform = tr.transform;
    return (*this);
  }
  
  /**
   * Static function to compute translation matrix from a vector.
   */
  static FMatrix4x4 translation (const FVector3& t) {
    FMatrix4x4 transmat;
    transmat[0][3] = t[0];
    transmat[1][3] = t[1];
    transmat[2][3] = t[2];
    return transmat;
  }

  /**
   * Static function to compute translation matrix from x, y, z values.
   */  
  static FMatrix4x4 translation (double tx, double ty, double tz) {
    FMatrix4x4 transmat;
    transmat[0][3] = tx;
    transmat[1][3] = ty;
    transmat[2][3] = tz;
    return transmat;
  }

  /**
   * Static function to compute rotation matrix about the x axis.
   */  
  static FMatrix4x4 rotation_x (double angle) {
    FMatrix4x4 rotmat;
    double ct = cos(angle), st = sin(angle);
    rotmat[0].set( 1,  0,  0, 0);
    rotmat[1].set( 0, ct, st, 0);
    rotmat[2].set( 0,-st, ct, 0);
    rotmat[3].set( 0,  0,  0, 1);
    return rotmat;
  }
  
  /**
   * Static function to compute rotation matrix about the y axis.
   */  
  static FMatrix4x4 rotation_y (double angle) {
    FMatrix4x4 rotmat;
    double ct = cos(angle), st = sin(angle);
    rotmat[0].set(ct, 0,-st, 0);
    rotmat[1].set( 0, 1,  0, 0);
    rotmat[2].set(st, 0, ct, 0);
    rotmat[3].set( 0, 0,  0, 1);
    return rotmat;
  }
  
  /**
   * Static function to compute rotation matrix about the z axis.
   */  
  static FMatrix4x4 rotation_z (double angle) {
    FMatrix4x4 rotmat;
    double ct = cos(angle), st = sin(angle);
    rotmat[0].set( ct, st, 0, 0);
    rotmat[1].set(-st, ct, 0, 0);
    rotmat[2].set(  0,  0, 1, 0);
    rotmat[3].set(  0,  0, 0, 1);
    return rotmat;
  }
  
  /**
   * Static function to compute scale matrix from a vector.
   */  
  static FMatrix4x4 scaling (const FVector3& s) {
    FMatrix4x4 scmat;
    scmat[0][0] = s[0];
    scmat[1][1] = s[1];
    scmat[2][2] = s[2];
    return scmat;
  }

  /**
   * Static function to compute scale matrix from x, y, z values.
   */
  static FMatrix4x4 scaling (double sx, double sy, double sz) {
    FMatrix4x4 scmat;
    scmat[0][0] = sx;
    scmat[1][1] = sy;
    scmat[2][2] = sz;
    return scmat;
  }
  
  /**
   * Combining two FTransformations.
   * Post-multiply with given FTransformation.
   */
  void operator *= (const FTransformation& tr) {
    transform *= tr.transform;
  }

  /**
   * Combining FTransformation and matrix.
   * Post-multiply with given matrix.
   */  
  void operator *= (const FMatrix4x4& mat) {
    transform *= mat;
  }
  
  /** 
   * Pre-multiply with given FTransformation/matrix
   * The operator chosen is not the most intuitive, but the only one that makes
   * some kind of sense
   */
  void operator /= (const FTransformation& tr) {
    transform = tr.transform * transform;
  }

  /** 
   * Pre-multiply with given FTransformation/matrix
   * The operator chosen is not the most intuitive, but the only one that makes
   * some kind of sense.
   */
  void operator /= (const FMatrix4x4& mat) {
    transform = mat * transform;
  }
  
  FTransformation operator * (const FTransformation& tr) {
    FTransformation newtr(*this);
    newtr *= tr;
    return newtr;
  }
  
  FTransformation operator * (const FMatrix4x4& mat) {
    FTransformation newtr(*this);
    newtr *= mat;
    return newtr;
  }
  
  friend FTransformation operator * (const FMatrix4x4& mat, const FTransformation& tr) {
    FTransformation newtr(mat);
    newtr *= tr;
    return newtr;
  }

  /**
   * Invert the FTransformation matrix.
   */
  void invert (void) {
    transform.invert();
  }
  
  // Apply FTransformations - pre-multiply by corresponding FTransformation matrices
  void translate (const FVector3& t) {
    transform = FTransformation :: translation(t) * transform;
  }
  
  void translate (double tx, double ty, double tz) {
    transform = FTransformation::translation (tx,ty,tz) * transform;
  }
  
  void rotate_x (double angle) {
    transform = FTransformation::rotation_x (angle) * transform;
  }
  
  void rotate_y (double angle) {
    transform = FTransformation::rotation_y (angle) * transform;
  }
  
  void rotate_z (double angle) {
    transform = FTransformation::rotation_z (angle) * transform;
  }

  /**
   * Rotate according to the rotation specified by the FQuaternion.
   */
  void rotate (const FQuaternion& quat) {
    transform = quat.to_matrix4() * transform;
  }
  
  void scale (const FVector3& s) {
    transform = FTransformation :: scaling(s) * transform;
  }
  
  void scale (double sx, double sy, double sz) {
    transform = FTransformation :: scaling(sx,sy,sz) * transform;
  }
  
  /**
   * Apply FTransformations - post-multiply
   */
  void post_translate (const FVector3& t) {
    transform *= FTransformation :: translation(t);
  }
  
  void post_translate (double tx, double ty, double tz) {
    transform *= FTransformation :: translation(tx,ty,tz);
  }
  
  void post_rotateX (double angle) {
    transform *= FTransformation :: rotation_x(angle);
  }
  
  void post_rotateY (double angle) {
    transform *= FTransformation :: rotation_y(angle);
  }
  
  void post_rotateZ (double angle) {
    transform *= FTransformation :: rotation_z(angle);
  }

  /**
   * Rotate according to the rotation specified by the FQuaternion.
   */
  void post_rotate (const FQuaternion& quat) {
    transform *= quat.to_matrix4();
  }
  
  void post_scale (const FVector3& s) {
    transform *= FTransformation :: scaling(s);
  }
  
  void post_scale (double sx, double sy, double sz) {
    transform *= FTransformation :: scaling(sx,sy,sz);
  }
  
  /**
   * Apply the FTransformation in OpenGL. Calls only glMultMatrix.
   */
  void apply (void) const {
    double mat[16];
    transform.fill_array_column_major(mat);
    glMultMatrixd(mat);
  }
  
  /**
   * Get the FTransformation matrix.
   */
  FMatrix4x4 matrix (void) {
    return transform;
  }
  
  /**
   * Reset the FTransformation matrix.
   */
  void reset (void) {
    transform.reset();
  }
  
  /**
   * Set the FTransformation matrix.
   */
  void set (const FMatrix4x4 mat) {
    transform = mat;
  }

protected:
  
  // Combined FTransformation matrix
  FMatrix4x4 transform;
  
};

#endif

--- NEW FILE: FImage.H ---
/* -*-C++-*- 

   "$Id: FImage.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FIMAGE_H_
#define _FIMAGE_H_

typedef unsigned char uchar;

class FImage;

class FImageIterator {

 private:
  
  friend class FImage;

  FImageIterator (uchar *p, int c=4) : ptr (p), channels (c) { }

 public:

  FImageIterator () : ptr (0), channels (4) { }

  bool operator == (FImageIterator &p) const { return (ptr == p.ptr); }

  bool operator != (FImageIterator &p) const { return (ptr != p.ptr); }

  FImageIterator operator++ () 
    { 
      ptr += channels;
      return *this;
    }

  FImageIterator operator++ (int)
    {
      FImageIterator tmp = *this;
      ptr += channels;
      return tmp;
    }

  FImageIterator operator-- ()
    {
      ptr -= channels;
      return *this;
    }

  FImageIterator operator-- (int)
    {
      FImageIterator tmp = *this;
      ptr -= channels;
      return tmp;
    }

  FImageIterator& operator = (const FImageIterator &p)
    {
      ptr = p.ptr;
      return *this;
    }

  uchar* operator* () { return ptr; }

 protected:
  
  uchar *ptr;
  int channels;
};


/** @package libflek_core
 * FImage provides four 8 bit channels (Red, Green, Blue and Alpha).
 * The image is stored internally as an array of unsigned chars in
 * RGBA order.  The internal representation can be used directly by
 * OpenGL with the GL_RGBA format and the GL_UNSIGNED_BYTE type.
 */
class FImage
{
  
 public:

  typedef FImageIterator iterator;

  /**
   * The default constructor does not allocate any space for the image.
   */
  FImage ();

  /**
   * This constructor allocated W*H pixels for storing the image.
   */
  FImage (int w, int h, int channels=4);

  /**
   * The copy constructor.
   */
  FImage (FImage *src);
  
  /** 
   * The destructor deallocated any allocated memory.
   */
  ~FImage ();

  //void width (int i) { W = i; }
  //void height (int i) { H = i; }

  /**
   * Gets the width of the image.
   */
  int width () { return W; }

  /**
   * Gets the height of the image.
   */
  int height () { return H; }

  /**
   * Gets the number of channels.
   */
  int channels () { return Channels; }

  /** 
   * A really bad scale function.
   */
  FImage* scale (int w, int h);

  void flip_vertical ();
  
  /** 
   * Clear the image to a certain color.
   */
  void clear (uchar r=0, uchar g=0, uchar b=0, uchar a=0);
  
  /**
   * Sets the number of channels.  Crops or expands the number of channels.
   */
  void channels (int c);
  
  /**
   * Return an iterator connected to the first pixel on row r of the image.
   */
  iterator begin (int r) { return iterator (Data+Channels*W*r, Channels); }

  /**
   * Return an iterator connected to the first pixel in the image.
   */
  iterator begin () { return iterator (Data, Channels); }

  /**
   * Return an iterator connected to the last+1 pixel on row r of the image.
   */
  iterator end (int r) { return iterator (Data+(Channels*W*(r+1)), Channels); }

  /**
   * Return an iterator connected to the last+1 pixel in the image.
   */
  iterator end () { return iterator (Data+(W*H*Channels), Channels); }

  /**
   * Return an iterator connected to position x, y.
   */
  iterator operator() (int x, int y) { return iterator (Data+((W*y)+x)*Channels, Channels); }

  FImage& operator = (const FImage &p) {
    delete [] Data;
    W = p.W;
    H = p.H;
    Channels = p.Channels;
    Data = new uchar [W*H*Channels];
    for (int i=0; i<W*H*Channels; i++) {
      Data[i] = p.Data[i];
    }
    return *this;
  }
  
 protected:

  uchar *Data;
  int W;
  int H;
  int Channels;

};

/**
 * Composite image B "over" image A in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* composite (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Composite src "over" dest, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void composite (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Add image B to image A in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* add (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Add src to dest, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void add (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Subtract image B from image A in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* subtract (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Subtract src from dest, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void subtract (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Create a difference from images A and B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* difference (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * The difference of src and dest, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void difference (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Lighten image A from Image B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* lighten_only (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Use the maximum (lightest) value of src and dest, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void lighten_only (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Darken image A from Image B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* darken_only (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Use the minimum (darkest) value of src and dest, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void darken_only (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Divide image A by Image B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* divide (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Divide dest by src, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void divide (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Multiply image A by Image B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* multiply (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Multiply dest by src, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void multiply (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Screen image A by Image B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* screen (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Screen dest by src, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void screen (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

/**
 * Overlay image A by Image B in place.  Image B can be offset by xo, yo. 
 * And the operation may have an opacity o.
 */
FImage* overlay (FImage *A, FImage *B, int xo=0, int yo=0, float o=1.0);

/**
 * Overlay dest by src, where src and dest are an array of unsigned
 * chars in RGBA order.  opacity is an integer value from 0-255 that 
 * gives the src frame an overall opacity/transparency.  length is the
 * number of RGBA pixels to perform this operation on.
 */
void overlay (unsigned char* dest, const unsigned char* src, int opacity, int length, int dest_channels, int src_channels);

#endif

--- NEW FILE: FTrans_Control.H ---
/* -*-C++-*- 

   "$Id: FTrans_Control.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FTRANS_CONTROL_H_
#define _FTRANS_CONTROL_H_

#include <Flek/FVector3.H>
#include <Flek/FMatrix4x4.H>

/**
 * @package libflek_gl
 * 
 * Class for a translation controller
 */
class FTrans_Control {

protected:

  // Current transformation matrix
  FMatrix4x4 mNow;
  bool Dragging;

  // Mouse translations/points
  FVector3 vNow, vDown;

  // Current translation
  FVector3 tNow, tDown;

public:
  
  /**
   * Default constructor.
   */
  FTrans_Control ()
    : mNow(), Dragging(false), vNow(), vDown(), tNow(), tDown()
  {}
  
  /**
   * Copy constructor.
   */
  FTrans_Control (const FTrans_Control& tc)
    : mNow(tc.mNow), Dragging(tc.Dragging), vNow(tc.vNow), vDown(tc.vDown),
      tNow(tc.tNow), tDown(tc.tDown)
  {}
  
  /**
   * Destructor
   */
  ~FTrans_Control ()
  {}
  
  FTrans_Control& operator = (const FTrans_Control& tc) {
    mNow = tc.mNow; Dragging = tc.Dragging; vNow = tc.vNow; vDown = tc.vDown;
    tNow = tc.tNow; tDown = tc.tDown;
    return (*this);
  }
  
  void reset (void) {
    tNow.reset(); tDown.reset(); mNow.reset();
  }
  
  /**
   * Specify mouse position.
   */
  void mouse (const FVector3& pos) {
    vNow = pos;
  }
  
  /**
   * Specify mouse position.
   */
  void mouse (double x, double y, double z=0.0) {
    vNow.set(x,y,z);
  }
     
  /**
   * Get the translation matrix.
   */
  FMatrix4x4 value (void) const {
    return mNow;
  }

  /**
   * Get the translation FVector
   */
  FVector3 trans_value (void) const {
    return tNow;
  }
  
  /**
   * Begin a drag.
   */
  void begin_drag (void) {
    Dragging = true; vDown = vNow;
  }
  
  /** 
   * End a drag
   */
  void end_drag (void) {
    Dragging = false; tDown = tNow;
  }

  /**
   * Check dragging status.
   */
  bool dragging (void) const {
    return Dragging;
  }

  /**
   * Update the FVectors and matrices.
   */
  void update (void) {
    if (Dragging) {
      tNow = tDown; tNow += vNow; tNow -= vDown;
      
      // Fill in transposed order for GL
      mNow[3][0] = tNow[0];
      mNow[3][1] = tNow[1];
      mNow[3][2] = tNow[2];
    }
  }
};

#endif

--- NEW FILE: FVector2.H ---
/* -*-C++-*- 

   "$Id: FVector2.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
  
   Please report all bugs and problems to "flek-devel at sourceforge.net".
   
*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FVECTOR2_H_
#define _FVECTOR2_H_

#include <Flek/FVector.H>

/** @package libflek_core
 * fVector2 is a 2 dimensional vector represented internally as an array of 
 * doubles.  This class is related to fVector3 and fVector4 which are 
 * 3-D and 4-D versions of this class.  All fVector classes are forward
 * declared in fVector.h.
 */

class FVector2 : public FBase
{
  
public:

  typedef FVector2* Ptr;
  
  /**
   * The default constructor sets each element in the vector to 0.
   */
  FVector2 ()
    : FBase ()
    {
      elem[0] = elem[1] = 0.0;
    }
  
  /**
   * This one argument constructor intializes all elements in the vector
   * with the given value.
   */
  FVector2 (double val)
    : FBase ()
    {
      elem[0] = elem[1] = val;
    }

  /**
   * This one argument constructor initializes the vector with the first
   * three elements in the given array.
   */     
  FVector2 (double * arr)
    : FBase ()
    {
      elem[0] = arr[0]; elem[1] = arr[1];
    }
  
  /**
   * This two argument constructor initializes the vector with the
   * passed values.
   */
  FVector2 (double val1, double val2)
    : FBase ()
    {
      elem[0] = val1; elem[1] = val2;
    }

  /**
   * The copy constructor initializes this vector with the contents 
   * of another vector.
   */     
  FVector2 (const FVector2& vec)
    : FBase (vec)
    {
      elem[0] = vec.elem[0]; elem[1] = vec.elem[1];
    }

  /**
   * This constructor initializes the vector from the contents of a
   * FVector3.  The third element in the FVector3 is ignored.
   */
  FVector2 (const FVector3& vec)
    : FBase ()
    {
      copy_from (vec);
    }
     
  /**
   * This constructor initializes the vector from the contents of a
   * FVector4.  The third element in the FVector4 is ignored.
   */
  FVector2 (const FVector4& vec)
    : FBase ()
    {
      copy_from (vec);
    }

  /**
   * The virtual destructor does nothing.
   */
  virtual ~FVector2 ()
    {}

  /**
   * Assignment operator from another FVector2.
   */
  FVector2& operator = (const FVector2& vec)
    {
      elem[0] = vec.elem[0]; elem[1] = vec.elem[1];
      return (*this);
    }

  /** 
   * Assignment operator from a scalar.  All elements are set to 
   * the scalar value.
   */
  FVector2& operator = (double scalar)
    {
      elem[0] = elem[1] = scalar;
      return (*this);
    }

  /**
   * Assignment operator from a FVector3.  Copies first 2 elements.
   */
  FVector2& operator = (const FVector3& vec)
    {
      copy_from (vec);
      return (*this);
    }

  /**
   * Assignment operator from a FVector4.  Copies first 2 elements.
   */
  FVector2& operator = (const FVector4& vec)
    {
      copy_from (vec);
      return (*this);
    }

  /**
   * Make a copy of the object.
   */
  virtual FBase::Ptr copy (void) const
    {
      Ptr vec = new FVector2 (*this);
      return vec;
    }

  /** 
   * Set each element vector to the given values.
   */
  void set (double v1, double v2)
    {
      elem[0] = v1; elem[1] = v2;
    }
  
  /** 
   * Set each element vector to the given value.
   */
  void set (double val)
    {
      elem[0] = elem[1] = val;
    }
     
  /** 
   * Set elements of vector to default values.
   */
  void reset (void)
    {
      set(0.0);
    }

  /** 
   * Get the elements of vector into given values.
   */
  void get (double& v1, double& v2) const
    {
      v1 = elem[0]; v2 = elem[1];
    }

  /**
   * Fill an array with the elements of the vector.
   */
  void fill_array (double arr[2]) const
    {
      arr[0] = elem[0]; arr[1] = elem[1];
    }
     
  /** 
   * Element access operator.  For efficiency, this doesn't check for 
   * valid indices
   */
  double& operator [] (uint index)
    {
      return elem[index];
    }

  /** 
   * Element access operator.  For efficiency, this doesn't check for 
   * valid indices
   */
  double operator [] (uint index) const
    {
      return elem[index];
    }

  /**
   * Arithmetic operator for additive assignment.
   */
  void operator += (const FVector2& vec)
    {
      elem[0] += vec.elem[0]; elem[1] += vec.elem[1];
    }

  /**
   * Arithmetic operator for subtractive assignment.
   */
  void operator -= (const FVector2& vec) 
    {
      elem[0] -= vec.elem[0]; elem[1] -= vec.elem[1];
    }
  
  /**
   * Arithmetic operator for multiplicative (scalar) assignment.
   */
  void operator *= (double scalar)
    {
      elem[0] *= scalar; elem[1] *= scalar;
    }
    
  /**
   * Arithmetic operator for divisive (scalar) assignment.
   */ 
  void operator /= (double scalar)
    {
      elem[0] /= scalar; elem[1] /= scalar;
    }
    
  /**
   * Arithmetic operator for addition.
   */
  FVector2 operator + (const FVector2& vec) const
    {
      FVector2 sum(*this);
      sum += vec;
      return sum;
    }
  
  /**
   * Arithmetic operator for subtraction.
   */ 
  FVector2 operator - (const FVector2& vec) const
    {
      FVector2 diff(*this);
      diff -= vec;
      return diff;
    }
  
  /**
   * Operator for scalar multiplication (dot product).
   */
  double operator * (const FVector2& vec) const
    {
      double dotprod = elem[0]*vec.elem[0] + elem[1]*vec.elem[1];
      return dotprod;
    }

  /**
   * Friend operator for negation.
   */
  friend FVector2 operator - (const FVector2& vec)
    {
      FVector2 negv (-vec.elem[0], -vec.elem[1]);
      return negv;
    }
  
  /**
   * Friend operator for scalar pre-multiplication.
   */
  friend FVector2 operator * (double scalar, const FVector2& vec)
    {
      FVector2 prod (vec);
      
      prod *= scalar;
      return prod;
    }

  /**
   * Friend operator for scalar post-multiplication.
   */  
  friend FVector2 operator * (const FVector2& vec, double scalar)
    {
      FVector2 prod (vec);
      
      prod *= scalar;
      return prod;
    }

  /**
   * Friend operator for scalar division.
   */
  friend FVector2 operator / (const FVector2& vec, double scalar)
    {
      FVector2 prod (vec);
      
      prod /= scalar;
      return prod;
    }

  /**
   * Friend operator for element-by-element product.
   */ 
  friend FVector2 product(const FVector2& vec1, const FVector2& vec2)
    {
      FVector2 prod(vec1[0]*vec2[0],vec1[1]*vec2[1]);
      
      return prod;
    }
     
  /**
   * Boolean equality operator.
   */       
  bool operator == (const FVector2& vec) const
    {
      if ( (fabs(elem[0]-vec.elem[0]) > ZERO) ||
	   (fabs(elem[1]-vec.elem[1]) > ZERO) )
	return false;
      return true;
    }

  /**
   * Boolean ineqality operator.
   */
  bool operator != (const FVector2& vec) const
    {
      return !( (*this) == vec );
    }

  /**
   * Square of the norm of the vector.
   */ 
  friend double normsqr(const FVector2& vec)
    {
      double nsq = sqr (vec.elem[0]) + sqr (vec.elem[1]);
      return nsq;
    }
     
  /**
   * Norm of the vector.
   */
  friend double norm (const FVector2& vec)
    {
      return sqrt (normsqr (vec));
    }

  /** 
   * Length (norm) of the vector.
   */
  double length ()
    {
      return norm (*this);
    }
  
  /**
   * Normalize.  Returns previous norm.
   */
  friend double normalize (FVector2& vec)
    {
      double n = norm (vec);
      if ( is_non_zero (n) == true ) vec /= n;
      return n;
    }

  /** 
   * Returns normalized vector.
   */
  friend FVector2 normalized (const FVector2& vec)
    {
      FVector2 nvec (vec);
      normalize (nvec);
      return nvec;
    }

  /**
   * Swap the elements of two FVector2s.
   */     
  friend void swap (FVector2& vec1, FVector2& vec2)
    {
      swap (vec1.elem[0], vec2.elem[0]);
      swap (vec1.elem[1], vec2.elem[1]);
    }

  /**
   * I/O Stream extraction operator.  Of the form "[ x y ]". 
   */ 
  friend istream& operator >> (istream& i, FVector2& vec)
    {
      remove_white_space (i);
      if ( i.peek() == '[' )
	{
	  // Correct format
	  int numread = 0;  // No. of elements read
	  double val;
	  char c;
	  
	  i >> c;  // Read opening square bracket
	  while ( numread < 2 )
	    {
	      i >> val; vec.elem[numread] = val;
	      numread++;
	    }
	  
	  // Read all characters till closing bracket is found
	  // If no. of chars read is more than 10 then print an error
	  // message and exit;
	  i >> c;
	  numread = 1;
	  while ( c != ']' && numread < 10 )
	    {
	      i >> c; numread++;
	    }
	  
	  if ( numread >= 10 )
	    {
	      cerr << "operator >> FVector2 : Incorrect format. Closing ']' not"
		   << " found upto 10 characters after 2nd element of vector"
		   << endl;
	      exit(0);
	    }
	}
      
      return i;
    }

  /**
   * I/O Stream insertion operator.  Of the form "[ x y z ]". 
   */ 
  friend ostream& operator << (ostream& o, const FVector2& vec)
    {
      // User can set precision from 0 to 6
      o << setiosflags(ios::fixed) << setiosflags (ios::showpoint);
      
      int oldprec = o.precision ();
      if ( oldprec < 0 ) o << setprecision(0);
      if ( oldprec > 6 ) o << setprecision(6);
      
      o << "["
	<< vec.elem[0] << " "
	<< vec.elem[1]
	<< "]";
      
      o << setprecision (oldprec);
      return o;
    }
  
protected:
  
  double elem[2];

  /**
   * Initialize the elements from a FVector3,
   */
  void copy_from (const FVector3& vec);

  /**
   * Initialize the elements from a FVector4,
   */
  void copy_from (const FVector4& vec);

};

#endif // #ifndef FVector2_H_


--- NEW FILE: Fl_Better_Window.H ---
#ifndef _FL_BETTER_WINDOW_H_
#define _FL_BETTER_WINDOW_H_

#include <FL/Fl_Window.H>

class Fl_Better_Window : public Fl_Window
{
 public:
  Fl_Better_Window (int x, int y, int w, int h, const char *l = 0) 
    : Fl_Window (x, y, w, h, l) {}

  static int get_window_borders (Fl_Window *win, 
                                 int &left, int &right, 
                                 int &top, int &bottom);
  
  int get_window_borders (int &left, int &right, 
			  int &top, int &bottom) 
    { 
      return get_window_borders (this, left, right, top, bottom);
    }
  
};

#endif

--- NEW FILE: Flv_List.H ---
//	*** TODO ***
//	Implement row styles, global styles
//	======================================================================
//	File:    Flv_List.h - Flv_List implementation
//	Program: Flv_List - FLTK Widget
//	Version: 0.1.0
//	Started: 11/21/99
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	Flv_List implements a scrollable list.  No data is stored
//	in the widget.  Supports headers/footers, natively supports a single
//	row height per list.	Row grids can be turned on and off.  Supports
//	no scroll bars as well as horizontal/vertical automatic or always
//	on scroll bars.
//	Uses absolute row references.
//
//	row -1 is defined as the row header
//	row -2 is defined as the row footer
//
// 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 FLV_LIST_H
#define FLV_LIST_H

#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Enumerations.H>
#include <Flek/Flv_Style.H>

#ifdef PIXIL
#include "nxscrollbar.h"
#include "nxapp.h"
#else
#include <FL/Fl_Scrollbar.H>
#endif

#define FLV_ROW_HEADER -1
#define FLV_ROW_FOOTER -2
#define FLV_TITLE -3

#define SLIDER_WIDTH 17

typedef unsigned char Flv_ShowScrollbar;
typedef unsigned short Flv_Feature;

//	Call back events
#define FLVE_ROW_CHANGED        1
#define FLVE_ROWS_CHANGED       2
#define FLVE_SELECTION_CHANGED  3
#define FLVE_COL_CHANGED        4
#define FLVE_COLS_CHANGED       5
#define FLVE_FEATURE_CHANGED    6
#define FLVE_CLICKED						7
#define FLVE_ENTER_PRESSED      8
#define FLVE_ROW_HEADER_CLICKED 9
#define FLVE_ROW_FOOTER_CLICKED 10
#define FLVE_COL_HEADER_CLICKED 11
#define FLVE_COL_FOOTER_CLICKED 12
#define FLVE_LABEL_CLICKED			13
#define FLVE_TITLE_CLICKED			14
#define FLVE_ALL_CLICKED				15

//	Call back when flags
#define FLVEcb_ROW_CHANGED        0x0001
#define FLVEcb_ROWS_CHANGED       0x0002
#define FLVEcb_SELECTION_CHANGED  0x0004
#define FLVEcb_COL_CHANGED        0x0008
#define FLVEcb_COLS_CHANGED       0x0010
#define FLVEcb_FEATURE_CHANGED    0x0020
#define FLVEcb_CLICKED						0x0040
#define FLVEcb_ENTER_PRESSED      0x0080
#define FLVEcb_ROW_HEADER_CLICKED 0x0100
#define FLVEcb_ROW_FOOTER_CLICKED 0x0200
#define FLVEcb_COL_HEADER_CLICKED 0x0400
#define FLVEcb_COL_FOOTER_CLICKED 0x0800
#define FLVEcb_LABEL_CLICKED			0x1000
#define FLVEcb_TITLE_CLICKED			0x2000
#define FLVEcb_ALL_CLICKED				0x4000

//	Feature list
#define FLVF_NONE							0
#define FLVF_ROW_HEADER				1
#define FLVF_ROW_FOOTER				2
#define FLVF_ROW_DIVIDER			4
#define FLVF_COL_HEADER				8
#define FLVF_COL_FOOTER			 16
#define FLVF_COL_DIVIDER		 32
#define FLVF_MULTI_SELECT		 64
#define FLVF_ROW_SELECT			128
#define FLVF_PERSIST_SELECT	256
#define FLVF_FULL_RESIZE    512
#define FLVF_DIVIDERS			(FLVF_COL_DIVIDER|FLVF_ROW_DIVIDER)
#define FLVF_HEADERS			(FLVF_ROW_HEADER|FLVF_COL_HEADER)
#define FLVF_FOOTERS			(FLVF_ROW_FOOTER|FLVF_COL_FOOTER)
#define FLVF_ROW_ENDS			(FLVF_ROW_HEADER|FLVF_ROW_FOOTER)
#define FLVF_COL_ENDS			(FLVF_COL_HEADER|FLVF_COL_FOOTER)
#define FLVF_ALL_ROW			(FLVF_ROW_HEADER|FLVF_ROW_FOOTER|FLVF_ROW_DIVIDER)
#define FLVF_ALL_COL			(FLVF_COL_HEADER|FLVF_COL_FOOTER|FLVF_COL_DIVIDER)

//	Scroll bar visibility
#define FLVS_NONE	0
#define FLVS_HORIZONTAL	1
#define FLVS_VERTICAL		2
#define FLVS_BOTH				(FLVS_HORIZONTAL|FLVS_VERTICAL)

#define FLVS_AUTOMATIC	0
#define FLVS_ALWAYS			4

#define FLVS_HORIZONTAL_ALWAYS	(FLVS_HORIZONTAL|FLVS_ALWAYS)
#define FLVS_VERTICAL_ALWAYS		(FLVS_VERTICAL|FLVS_ALWAYS)
#define FLVS_BOTH_ALWAYS				(FLVS_BOTH|FLVS|FLVS_ALWAYS)

//	Edit when constants
#define FLV_EDIT_ALWAYS				1
#define FLV_EDIT_AUTOMATIC    2
#define FLV_EDIT_MANUAL		    3

class Flv_List : public Fl_Group
{
public:
#ifdef PIXIL
  NxScrollbar scrollbar;		// Vertical scrollbar
  NxScrollbar hscrollbar;	// Horizontal scrollbar
#else
	Fl_Scrollbar scrollbar;		// Vertical scrollbar
	Fl_Scrollbar hscrollbar;	// Horizontal scrollbar
#endif

	Flv_List( int X, int Y, int W, int H, const char *l=0 );
	~Flv_List();

	virtual int row_height( int n );
	virtual int row_height( int n, int R );

	virtual void get_style(Flv_Style &s, int R, int C=0);	//	get trickle down style

	void add_selection_style( Flv_Style &s, int R, int C=0 );	//	Add selection style

	virtual void save_editor( Fl_Widget *e, int R, int C=0 );	//	Save editor contents
	virtual void load_editor( Fl_Widget *e, int R, int C=0 );	//	Load editor contents
	virtual void position_editor( Fl_Widget *e, int x, int y, int w, int h, Flv_Style &s );

	int callback_when(void)											//	Get callback when
		{	return vcallback_when;	}
	int callback_when(int v)										//	Set callback when
		{	return vcallback_when = v;	}
	int add_callback_when(int v)								//	Add callback conditions
		{	return vcallback_when |= v;	}
	int clear_callback_when(int v)							//	Clear callback conditions
		{	return vcallback_when &= ~v;	}
	bool callback_on(int v)											//	See if callback should be done
		{	return (vcallback_when & v)==v;	}
	int edit_when(void)													//	Get when to edit
		{	return vedit_when;	}
	int edit_when( int v );											//	Set when to edit

	void start_edit(void);											//	Start editing
	void end_edit(void);												//	End editing (w/save)
	void cancel_edit(void);											//	Cancel editing (wo/save)
	Fl_Widget *editor(void)											//	Return current editor
		{	return veditor;	}
	int bottom_row(void);												//	Return last partially visible row

	unsigned char clicks()											//	# of clicks 1, 2, 3...
		{	return vclicks;	}
	void clear_clicks(void)											//	Reset # of clicks
		{	vclicks = 0;	}
	unsigned char max_clicks(void)							//	Get Max # of clicks
		{	return vmax_clicks;	}
	unsigned char max_clicks(unsigned char n)		//	Return max # of clicks
		{	return vmax_clicks=n;	}

	Fl_Color dead_space_color(void) const				//	Get dead space color
		{	return vdead_space_color;	}
	Fl_Color dead_space_color(Fl_Color &n)			//	Set dead space color
	{	return (vdead_space_color = n);	}

	Flv_Feature feature(void)										//	Get features
		{	return vfeature;	}
	Flv_Feature feature(Flv_Feature v);					//	Set features
	Flv_Feature feature_add(Flv_Feature v);			//	Add (set of) feature(s)
	Flv_Feature feature_remove(Flv_Feature v);	//	Remove (set of) feature(s)
	bool feature_test(Flv_Feature v)						//	Test if (set of) feature(s) on
		{	return ((vfeature&v)==v);	}

	//	Convenience funtions to test if a feature is ON.
	bool row_footer(void)					//	Row footer convenience function
		{	return feature_test(FLVF_ROW_FOOTER);	}
	bool row_header(void)					//	Row header convenience function
		{	return feature_test(FLVF_ROW_HEADER);	}
	bool row_divider(void)				//	Row divider convenience function
		{	return feature_test(FLVF_ROW_DIVIDER);	}
	bool multi_select(void)				//	Multi-select convenience function
		{	return feature_test(FLVF_MULTI_SELECT);	}
	bool persist_select(void)			//	Persistant selection test
		{	return feature_test(FLVF_PERSIST_SELECT);	}
	bool full_resize(void)				//	Full widget resize test
		{	return feature_test(FLVF_FULL_RESIZE);	}

	void get_default_style( Flv_Style &s );	//	Fill in s with default style
	int get_row( int x, int y );						//	Get row from X value

	bool get_cell_bounds( int &X, int &Y, int &W, int &H, int R, int C=0 );

	Flv_ShowScrollbar has_scrollbar(void)	//	Get/set scrollbar visibility
		{	return vhas_scrollbars;	}
	Flv_ShowScrollbar has_scrollbar( Flv_ShowScrollbar v );

	bool move_row(int amount);						//	Change row # by amount

	int row(void)									//	Get/set current row
		{	return vrow;	};
	int row(int n);

	bool row_resizable( int r );					//	Get/Set row locked status
	bool row_resizable( bool n, int r );

	int row_offset(void)					//	Get/Set current row offset
		{	return vrow_offset;	}
	int row_offset( int n );

	int rows(void) 								//	Get/Set total # of rows
		{	return vrows;	};
	int rows(int n);

	int rows_per_page(void)				//	Get/set # of rows / page
		{	return vrows_per_page;	}
	int rows_per_page( int n );		//	Use 0 to allow calculating

	bool row_selected(int n);			//	Is row selected?

	int row_width(void)						//	Get/set total row width
		{	return vrow_width;	};
	int row_width( int n );

	int scrollbar_width(void)			//	Get/set scrollbar thickness
		{	return vscrollbar_width;	}
	int scrollbar_width(int n);

	bool select_locked(void)						//	Allow selecting locked rows/cols?
		{	return vselect_locked;	}
	bool select_locked(bool n)					//	Set whether allowing selection of 
		{	return (vselect_locked=n);	}		//		locked rows/cols

	int select_start_row(void)				//	Get first selected row
		{	return vselect_row;	}
	int select_start_row(int n);			//	Set first selected row

	int top_row(void)									//	Get the current top row
		{	return vtop_row;	}
	int top_row(int v)
		{	return (vtop_row=v);	};			//	Set the top row (Hint only)

  int why_event()										//	Why was the event called?
  	{	return vwhy_event;	}
  int why_event( int n )						//	Set why the event was called
  	{	return (vwhy_event=n);	}

	//	Style routines
	Flv_Style global_style;		//	Global style
	Flv_Style_List row_style;	//	Row styles
protected:
	unsigned char vmax_clicks;										//	Max clicks allowed
	unsigned char vclicks;
	int vedit_when;											//	When does editing start
	int edit_row;
	void switch_editor( int nr );
	Fl_Widget *veditor;									//	Current editor
	bool vediting;											//	Are we editing now?
	int vwhy_event;											//	Why was event called
	int vlast_row;											//	Last row highlighted
	void update_top_row(int H);
	int handle(int event);
	void start_draw(int &X, int &Y, int &W, int &H, int &rw);
	virtual void draw_row( int Offset, int &X, int &Y, int &W, int &H, int R );
	void draw_border(Flv_Style &s, int &X, int &Y, int &W, int &H );
	void client_area( int &X, int &Y, int &W, int &H );
	void draw_scrollbars( int &X, int &Y, int &W, int &H );
	void draw();
	int page_size(void);								//	Calculate useable page size

	int vrow;														//	Current selected row

private:
#ifdef FLEK_FLTK_2
	static Fl_Style* default_style;
#endif
	void check_cursor(void);		//	Check if resizing allowed here
	bool check_resize(void);		//	true if resizing
	int vcallback_when;									//	When to call back
	Fl_Color vdead_space_color;					//	Dead space color
	Flv_ShowScrollbar vhas_scrollbars;	//	determine scroll bar visibility
	Flv_Feature vfeature;								//	Features (Headers, footers, dividers)
	int vrow_offset;										//	Current left offset for display
	int vrow_width;											//	Total pixel width
	int vrows;													//	Total # of rows to display
	int vrows_per_page;									//	# of rows to advance/page
	bool vselect_locked;								//	Selected locked entries or skip?
	int vselect_row;										//	First selected row
	int vscrollbar_width;								//	"thickness" of scrollbar
	int vtop_row;												//	Current top row
};

#endif

--- NEW FILE: FBase.H ---
/* -*-C++-*- 

   "$Id: FBase.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
  
   Please report all bugs and problems to "flek-devel at sourceforge.net".
   
*/

#ifndef _FBASE_H_
#define _FBASE_H_

/** @package libflek_core
 * FBase is the Abstract base class for all f classes.  The FBase
 * class can be used to build container classes which use object 
 * pointers.  The same container class can then be used with any
 * derived classes without the need of any additional code or templates.
 *
 * FBase has no member data.  It only has protected constructors (to 
 * prevent instantiation), virtual destructors and an assignment operator.
 */
class FBase
{
  
 public:

  typedef FBase* Ptr;

  /**
   * Assignment operator.  This operator must be overriden to be useful,
   * it's default behavior is to do nothing.
   * 
   * @param src
   */
  FBase& operator = (const FBase&) {
    return *this;
  }

  /**
   * Destructor.
   */
  virtual ~FBase () {}

  /**
   * Derived class should give a meaningful implementation
   * for the following functions.
   *
   * Classes such as List which use FBase pointers
   * will use these functions, for memory management
   * 
   * Make a copy of the FBase and return a pointer to the new one.
   */
  virtual Ptr copy () const = 0;

protected:
  
  /**
   * The default constructor is protected to prevent instantiation,
   */
  FBase () {}

  /** 
   * The copy constructor is protected to prevent instantiation.
   * 
   * @param src The class to take initial data from.
   */
  FBase (const FBase&) {}
};

#endif // #ifndef FBASE_H_


--- NEW FILE: Flv_Table.H ---
//	======================================================================
//	File:    Flv_Table.h - Flv_Table implementation
//	Program: Flv_Table - FLTK Widget
//	Version: 0.1.0
//	Started: 11/21/99
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	Flv_Table implements a table/grid.  No data is stored
//	in the widget.  Supports headers/footers for rows and columns,
//	natively supports a single row height and column width per table.
//	Row and column grids can be turned on and off.  Supports no scroll
//	bars as well as horizontal/vertical automatic or always on scroll bars.
//	Also support cell selection and row selection modes.  In row selection
//	mode it acts like a pumped-up list widget.
//
//	row -1 is defined as the row header
//	row -2 is defined as the row footer
//	column -1 is defined as the column header
//	column -2 is defined as the column footer
//
// 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 FLV_TABLE_H
#define FLV_TABLE_H

#include <Flek/Flv_List.H>

#define FLV_COL_HEADER -1
#define FLV_COL_FOOTER -2

#define FLV_MOVE_ON_ENTER_ROW_COL   1
#define FLV_MOVE_ON_ENTER_COL_ROW   2
#define FLV_MOVE_ON_ENTER_NEVER     3

#define FLV_BUTTON1 1
#define FLV_BUTTON2 2
#define FLV_BUTTON3 4


class Flv_Table : public Flv_List
{
public:
	Flv_Table( int X, int Y, int W, int H, const char *l=0 );
	~Flv_Table();

	virtual int col_width(int c);					//	Get column width
	virtual int col_width(int n, int c);	//	Set column width

	//	Add selection info if applicable
	void add_selection_style( Flv_Style &s, int R, int C=0 );

	int buttons(void)
		{	return vbuttons;	}
	int buttons(int v)
		{	return (vbuttons=v);	}
		
	void cell_area( int &X, int &Y, int &W, int &H);

	bool cell_selected(int R, int C);			//	Is cell selected?

	//	Convenience functions to tell if a feature is ON.
	bool col_footer(void)									//	Column footer convenience function
		{	return (Flv_Feature)(feature() & FLVF_COL_FOOTER)!=0;	}
	bool col_header(void)									//	Column header convenience function
		{	return (Flv_Feature)(feature() & FLVF_COL_HEADER)!=0;	}
	bool col_divider(void)								//	Column divider convenience function
		{	return (Flv_Feature)(feature() & FLVF_COL_DIVIDER)!=0;	}
	bool select_row(void)									//	Selecting row convenience function
		{	return feature_test(FLVF_ROW_SELECT);	}

	//	These are guaranteed style retrieval functions and get
	//	the trickle down style information.  Any style elements
	//	not defined are set to default values.
	virtual void get_style( Flv_Style &s, int R, int C=0 );
	int edit_when(void)													//	Get when to edit
		{	return vedit_when;	}
	int edit_when( int v );								//	When to edit

	bool move_row(int amount);						//	# of rows to move
	bool move_col(int amount);						//	# of cols to move
	int col(void)													//	Get current column #
		{	return vcol;	}
	int col( int n );											//	Set current column #
	int row(void)													//	Get current row #
		{	return vrow;	}
	int row(int n);												//	Set current row #

	bool col_resizable(int c);								//	Get/set column locked status
	bool col_resizable( bool n, int c);

	int cols(void)                        //	Get number of columns
		{	return vcols;	}
	int cols( int n );										//	Set number of columns

	bool col_selected(int n);							//	Is column selected

	bool get_cell_bounds( int &X, int &Y, int &W, int &H, int R, int C );
	
	int get_col( int x, int y );					//	Get column from x,y

	int move_on_enter(void) const					//	How do we move when enter pressed?
		{	return vmove_on_enter;	}
	int move_on_enter(int v)							//	Set how we move on enter
		{	return (vmove_on_enter=v);	}

	int select_start_col(void)						//	Get column selection starts in
		{	return vselect_col;	}
	int select_start_col(int n);					//	Set column selection starts in

	void start_edit(void);								//	Start editing
	void end_edit(void);									//	End editing (with save)
	void cancel_edit(void);								//	Cancel editing (no save)
	
	Flv_Style_List col_style;							//	Column styles

protected:
	int edit_col;
	void switch_editor( int nr, int nc );
	void draw(void);
	int handle(int event);
	int internal_handle(int event);
	virtual void draw_row( int Offset, int &X, int &Y, int &W, int &H, int R );
	virtual void draw_cell( int Offset, int &X, int &Y, int &W, int &H, int R, int C );

private:
	void check_cursor(void);		//	Check if resizing allowed here
	bool check_resize(void);		//	true if resizing

	void update_width();				//	Update scroll width
	void adjust_for_cell();			//	Guarantee cell is as visible as possible
	int vbuttons;								//	Click buttons
	int vcol;										//	Current column
	short vcol_width;						//	Default width
	int vcols;									//	Total # of columns
	int vmove_on_enter;					//	How to move when enter pressed.
	int vselect_col;						//	First column selected
};
#endif


--- NEW FILE: Fl_Gl_Arcball_Window.H ---
/* -*-C++-*- 

   "$Id: Fl_Gl_Arcball_Window.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
  
   Please report all bugs and problems to "flek-devel at sourceforge.net".
   
*/

#ifndef _FL_GL_ARCBALL_WINDOW_H_
#define _FL_GL_ARCBALL_WINDOW_H_


// Define macros for FLTK mouse buttons.
#define FL_LEFT_MOUSE 1
#define FL_MIDDLE_MOUSE 2
#define FL_RIGHT_MOUSE 3

#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <GL/gl.h>
#include <GL/glu.h>
#include <Flek/FTransformation.H>
#include <Flek/FArcball_Control.H>
#include <Flek/FTrans_Control.H>
#include <Flek/FZoom_Control.H>
#include <Flek/FDolly_Control.H>
#include <stdio.h>

enum TransformType { None=0, Pan=1, Rotate=2, Zoom=3, Dolly=4 };
enum ProjectionType { Orthographic=0, Perspective=1 };

/**
 * @package libflek_gl
 * 
 * Class for a FLTK GL Arcball window, which handles arcball rotations by default
 */
class Fl_Gl_Arcball_Window : public Fl_Gl_Window {
  
protected:
  
  FArcball_Control arcball;                                  // The arcball controller
  FTrans_Control trcontrol;                           // Translation controller
  FZoom_Control zoomcontrol;                          // Zoom controller
  FDolly_Control dollycontrol;                        // Dolly controller (10.0 scale)
  
  FTransformation transform;                         // Combined transformation
  TransformType currenttr;                          // Current transformation
  
  // View/projection parameters
  ProjectionType projtype;                          // Ortho/Perspective projection
  
  // For perspective projection
  double fovy;                                      // Field-of-view in degrees in y
  double aspect;                                    // Ratio of width to height
  double near;                                      // Near clipping plane
  double far;                                       // Far clipping plane
  
  // For orthographic projection
  double umin,umax,vmin,vmax;                       // Viewing frustum
  
  double cenx, ceny, cenz;                          // Center point for gluLookAt
  double eyex, eyey, eyez;                          // Eye point for gluLookAt
  double upx, upy, upz;                             // Up vector for gluLookAt
  double dist;                                      // Dist from eye pt to center pt
  
  FVector3 near_color_;
  FVector3 far_color_;
  FVector3 drag_color_;
  FVector3 rim_color_;
  
public:
  
  Fl_Gl_Arcball_Window(int x, int y, int w, int h, const char * l = NULL)
    : Fl_Gl_Window(x,y,w,h,l),
      arcball(FVector3(0,0,0),1.0), trcontrol(), zoomcontrol(), dollycontrol(10.0),
      transform(), currenttr(None),
      fovy(45.0), aspect(double(w)/double(h)), near(1.0), far(1000.0),
      umin(-1.0), umax(1.0), vmin(-1.0), vmax(1.0),
      cenx(0), ceny(0), cenz(0), eyex(0), eyey(0), eyez(50.0), upx(0), upy(1), upz(0)
  {}
  
  // Derived classes can override this
  virtual void reshape(void)
  {
    // This function should be called by the draw() function when the view
    // needs to be setup
    
    // This function sets up the view to be a perspective projection
    // using the view/projection parameters
    // Derived classes can override this function to do an orthographic projection
    // or they can change the view parameters and then call this function
    // If a perspective projection is set up using glFrustum instead of gluPerspective,
    // the fovy and aspect should be calculated and set correctly
    glViewport(0,0,w(),h());
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if ( projtype == Perspective ) 
      gluPerspective(fovy,aspect,near,far);
    else if ( projtype == Orthographic)
      glOrtho(umin,umax,vmin,vmax,near,far);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(eyex,eyey,eyez,cenx,ceny,cenz,upx,upy,upz);
    
    dist = sqrt( sqr(cenx-eyex) + sqr(ceny-eyey) + sqr(cenz-eyez) );
  }
  
  // Handle rotation by mouse. Will do the rotation irrespective of which mouse
  // button was used and irrespective of other modifiers. Does not call
  // redraw or return any value. Will always update the controller. So this
  // function should be called only when rotation is required
  virtual void handle_rotate(int event) {
    // Don't do anything if we aren't in a neutral state or aren't rotating
    if ( currenttr != None && currenttr != Rotate ) return;
    
    double x,y;
    
    currenttr = Rotate;
    
    // Transform coords to lie between -1 to 1
    x = ( double(Fl::event_x() << 1) / w() ) - 1.0;
    y = ( -double(Fl::event_y() << 1) / h() ) + 1.0;
    
    arcball.mouse(x,y); arcball.update();
    
    if ( event == FL_PUSH ) arcball.begin_drag();
    else if ( event == FL_RELEASE ) {
      arcball.end_drag();
      transform.rotate(arcball.quaternion_value());  // Update the combined transformation
      arcball.reset(); currenttr = None;
    }
  }
  
  // Handle panning by mouse. Will do the panning irrespective of which mouse
  // button was used and irrespective of other modifiers. Does not call
  // redraw or return any value. Will always update the controller. So this
  // function should be called only when panning is required
  virtual void handle_pan(int event) {
    // Don't do anything if we aren't in a neutral state or aren't panning
    if ( currenttr != None && currenttr != Pan ) return;
    
    double x, y;
    double tx=0, ty=0;
    
    currenttr = Pan;
    
    // Transform coords to lie between -1 to 1
    x = ( double(Fl::event_x() << 1) / w() ) - 1.0;
    y = ( -double(Fl::event_y() << 1) / h() ) + 1.0;
    
    // Adjust the x and y values so that moving mouse by 1 pixel
    // on screen moves point under mouse by 1 pixel
    if ( projtype == Orthographic ) {
      // Orthographic projection
      tx = umin*(1.0-x)*0.5 + umax*(1.0+x)*0.5;
      ty = vmin*(1.0-y)*0.5 + vmax*(1.0+y)*0.5;
    }
    else if ( projtype == Perspective ) {
      // Perspective projection
      tx = x*dist*tan(deg2rad(fovy*aspect*0.5));
      ty = y*dist*tan(deg2rad(fovy*0.5));
    }
    trcontrol.mouse(tx,ty); trcontrol.update();
    
    if ( event == FL_PUSH ) trcontrol.begin_drag();
    else if ( event == FL_RELEASE ) {
      trcontrol.end_drag();
      transform.translate(trcontrol.trans_value());// Update the combined transformation
      trcontrol.reset(); currenttr = None;
    }
  }
  
  // Handle zooming by mouse. Will do the zooming irrespective of which mouse
  // button was used and irrespective of other modifiers. Does not call
  // redraw or return any value. Will always update the controller. So this
  // function should be called only when zooming is required
  
  // Only the x movement is used for zooming. Zooming is done using the Zoom
  // controller which computes the apprpriate transformation matrix
  virtual void handle_zoom(int event) {
    // Don't do anything if we aren't in a neutral state or aren't zooming
    if ( currenttr != None && currenttr != Zoom ) return;
    
    double z;
    
    currenttr = Zoom;
    
    // Transform coords to lie between -1 to 1
    z = ( double(Fl::event_x() << 1) / w() ) - 1.0;
    
    // Currently both orthographic and perspective zoom is handled by same
    // controller which simply does a scaling
    /*
      if ( projtype == Orthographic )
      {
      }
      else if ( projtype == Perspective )
      {
            }
            */
    zoomcontrol.mouse(z); zoomcontrol.update();
    
    if ( event == FL_PUSH ) zoomcontrol.begin_drag();
    else if ( event == FL_RELEASE )
      {
	zoomcontrol.end_drag();
	transform.scale(zoomcontrol.zoom_value());// Update the combined transformation
	zoomcontrol.reset(); currenttr = None;
      }
  }
  
  // Handle dollying by mouse. Will do the dollying irrespective of which mouse
  // button was used and irrespective of other modifiers. Does not call
  // redraw or return any value. Will always update the controller. So this
  // function should be called only when dollying is required
  
  // Only the x movement is used for dollying. Dollying is done using the Dolly
  // controller which computes the appropriate transformation matrix
  // The transformation from dollying is not multiplied onto the transformation
  // matrix since this should be done outside of all other transformations
  virtual void handle_dolly(int event) {
    // Don't do anything if we aren't in a neutral state or aren't dollying
    if ( currenttr != None && currenttr != Dolly ) return;
    
    double z;
    
    currenttr = Dolly;
    
    // Transform coords to lie between -1 to 1
    z = ( double(Fl::event_x() << 1) / w() ) - 1.0;
    
    dollycontrol.mouse(z); dollycontrol.update();
    
    if ( event == FL_PUSH ) dollycontrol.begin_drag();
    else if ( event == FL_RELEASE ) {
      dollycontrol.end_drag();
      // Shouldn't reset since the value is directly used for transformations
      // separate from other transformations
      currenttr = None;
    }
  }
  
  // Implement handle() function for backward compatibility
  virtual int handle(int event) {
    if ( event == FL_PUSH || event == FL_RELEASE || event == FL_DRAG ) {
      if ( Fl::event_button() == FL_LEFT_MOUSE ) handle_rotate(event);
      else if ( Fl::event_button() == FL_MIDDLE_MOUSE ) handle_pan(event);
      else if (( Fl::event_button() == FL_RIGHT_MOUSE ) && Fl::event_state(FL_CTRL)) handle_dolly(event);
      else if ( Fl::event_button() == FL_RIGHT_MOUSE ) handle_zoom(event);
      
      if ( event != FL_PUSH ) redraw();
      return 1;
    }
    return Fl_Gl_Window::handle(event);
  }
  
  void arcball_draw(void);                           // Draw the arcball
  void drawConstraints (void) const;
  void drawDragArc (void);
  void arcball_transform(void) {                     // Apply the arcball transformation
    double mat[16];
    
    // Do the dollying separately before everything else
    glTranslated(0,0,dollycontrol.dolly_value());
    switch ( currenttr ) {
    case Pan :
      trcontrol.value().fill_array_row_major(mat);
      glMultMatrixd(mat);
      break;
    case Zoom :
      zoomcontrol.value().fill_array_row_major(mat);
      glMultMatrixd(mat);
      break;
    case Rotate :
      arcball.value().fill_array_row_major(mat);
      glMultMatrixd(mat);
      break;
    default:
      break;
    }
    transform.apply();
  }
  
  //--- Access arcball parameters ---//
  
  void arcball_center(const FVector3& cen)  {
    arcball.center(cen);
  }
  
  void arcball_radius(double rad) {
    arcball.radius(rad);
  }
  
  FVector3 arcball_center(void) const {
    return arcball.center();
  }
  
  double arcball_radius(void) const {
    return arcball.radius();
  }

  void reset () {
    transform.reset ();
  }
   
  /**
   * Get the current FArcball_Control being used for rotation.
   */
  FArcball_Control get_arcball () { return arcball; }
   
  /**
   * Set the current FArcball_Control being used for rotation.
   */
  void set_arcball (const FArcball_Control& arcball_) { arcball = arcball_; }
   
};

#endif

--- NEW FILE: math.H ---
/* -*-C++-*- 
   "$Id: math.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _INLINES_HH_
#define _INLINES_HH_

#include <math.h>
#include <Flek/types.H>

/*
 * Predefined constants, and macros
 * To change the values of some of these macros, define them before including
 * this file. Or dont include this file at all and define them on your own
 */

/**
 * @package libflek_core
 */

#ifndef _INLINE_ABS_
#define _INLINE_ABS_

/** 
 * Returns the absolute value.
 */
inline int absolute (int x)
{
  return (x < 0) ? -x : x;
}

/**
 * Returns the absolute value.
 */
inline float absolute (float x)
{
  return (x < 0.0) ? -x : x;
}

/**
 * Returns the absolute value.
 */
inline double absolute (double x)
{
  return (x < 0.0) ? -x : x;
}

#endif

// Zero '0' value to be used for comparison and assignment
#ifndef ZERO
#define ZERO 1.0e-10
#endif

// float infinity to be used for comparison and assignment
#ifndef FLT_INF
#define FLT_INF 1.0e35
#endif

// double infinity to be used for comparison and assignment
#ifndef DBL_INF
#define DBL_INF 1.0e100
#endif

#ifndef _INLINE_ZERO_CHECKS_
#define _INLINE_ZERO_CHECKS_

/**
 * Check if passed number is non-zero.
 */
inline bool is_non_zero (int num) {
  if ( num != 0 ) return true;
  return false;
}

/**
 * Check if passed number is non-zero.  (Uses ZERO bounds).
 */
inline bool is_non_zero (double num) {
  if ( (num < -ZERO) || (num > ZERO) ) return true;
  return false;
}

#endif

#ifndef _INLINE_FP_EQUAL_
#define _INLINE_FP_EQUAL_

inline bool are_equal (float x1, float x2) {
  return ( ( absolute (x1-x2) < ZERO ) ? true : false );
}

inline bool are_equal (double x1, double x2) {
  return ( ( absolute (x1-x2) < ZERO ) ? true : false );
}

#endif // #ifndef _INLINE_FP_EQUAL_


#ifndef _INLINE_ODD_EVEN_
#define _INLINE_ODD_EVEN_

/**
 * Check if passed number is odd.
 */
inline bool is_odd (int num) {
  if ( num % 2 ) return true;
  return false;
}

/**
 * Check if passed number is even.
 */
inline bool is_even (int num) {
  if ( num % 2 ) return false;
  return true;
}

/**
 * Check if passed number is odd.
 */
inline bool is_odd (uint num) {
  if ( num % 2 ) return true;
  return false;
}

/**
 * Check if passed number is even.
 */
inline bool is_even (uint num) {
  if ( num % 2 ) return false;
  return true;
}

#endif

#ifndef _INLINE_MATH_
#define _INLINE_MATH_

/**
 * Square the number.
 */
inline int sqr (int x) {
  return x*x;
}

/**
 * Cube the number.
 */
inline int cube (int x) {
  return x*x*x;
}

/**
 * Square the number.
 */
inline uint sqr (uint x) {
  return x*x;
}

/**
 * Cube the number.
 */
inline uint cube (uint x) {
  return x*x*x;
}

/**
 * Square the number.
 */
inline float sqr (float x) {
  return x*x;
}

/**
 * Cube the number.
 */
inline float cube (float x) {
  return x*x*x;
}

/**
 * Square the number.
 */
inline double sqr (double x) {
  return x*x;
}

/**
 * Cube the number.
 */
inline double cube (double x) {
  return x*x*x;
}

#endif

#ifndef _INLINE_MIN_MAX_
#define _INLINE_MIN_MAX_

/**
 * Minimum of two numbers.
 */
inline int min (int x, int y) {
  return ( (x < y) ? x : y );
}

/**
 * Maximum of two numbers.
 */
inline int max (int x, int y) {
  return ( (x > y) ? x : y );
}

/**
 * Minimum of two numbers.
 */
inline uint min (uint x, uint y) {
  return ( (x < y) ? x : y );
}

/**
 * Maximum of two numbers.
 */
inline uint max (uint x, uint y) {
  return ( (x > y) ? x : y );
}

inline ushort min (ushort x, ushort y) {
  return ( (x < y) ? x : y );
}

inline ushort max (ushort x, ushort y) {
  return ( (x > y) ? x : y );
}

/**
 * Minimum of two numbers.
 */
inline float min (float x, float y) {
  return ( (x < y) ? x : y );
}

/**
 * Maximum of two numbers.
 */
inline float max (float x, float y) {
  return ( (x > y) ? x : y );
}

/**
 * Minimum of two numbers.
 */
inline double min (double x, double y) {
  return ( (x < y) ? x : y );
}

/**
 * Maximum of two numbers.
 */
inline double max (double x, double y) {
  return ( (x > y) ? x : y );
}

/**
 * Minimum of two unsigned chars.
 */
inline unsigned char min (unsigned char x, unsigned char y) {
  return ( (x < y) ? x : y );
}

/**
 * Maximum of two unsigned chars.
 */
inline unsigned char max (unsigned char x, unsigned char y) {
  return ( (x > y) ? x : y );
}


#endif


#ifndef _INLINE_SWAP_
#define _INLINE_SWAP_

/**
 * Swap two numbers.
 */
inline void swap (int& x, int& y) {
  int t = x;
  x = y; y = t;
}

/**
 * Swap two numbers.
 */
inline void swap (uint& x, uint& y) {
  uint t = x;
  x = y; y = t;
}

/**
 * Swap two numbers.
 */
inline void swap (float& x, float& y) {
  float t = x;
  x = y; y = t;
}

/**
 * Swap two numbers.
 */
inline void swap (double& x, double& y) {
  double t = x;
  x = y; y = t;
}

#endif

#ifndef _INLINE_DEG_RAD_
#define _INLINE_DEG_RAD_

/**
 * Degrees to radians.
 */
inline float deg2rad (float deg) {
  return deg*M_PI/180.0;
}

/**
 * Degrees to radians.
 */
inline double deg2rad (double deg) {
  return deg*M_PI/180.0;
}

/**
 * Radians to degrees.
 */
inline float rad2deg (float rad) {
  return rad*180.0/M_PI;
}

/**
 * Radians to degrees.
 */
inline double rad2deg (double rad) {
  return rad*180.0/M_PI;
}

#endif

#ifndef _INLINE_SIGN_
#define _INLINE_SIGN_

/**
 * Return the sign of a number.  1, 0, or -1.
 */
inline int sign (int x) {
  return ( (x < 0) ? -1 : ((x > 0) ? 1 : 0) );
}

/**
 * Return the sign of a number.  1, 0, or -1.
 */
inline float sign (float x) {
  return ( (x < 0.0) ? -1.0 : ((x > 0.0) ? 1.0 : 0.0) );
}

/**
 * Return the sign of a number.  1, 0, or -1.
 */
inline double sign (double x) {
  return ( (x < 0.0) ? -1.0 : ((x > 0.0) ? 1.0 : 0.0) );
}

/**
 * For matrices - sign of cofactor. 1 if i+j is even, -1 if i+j is odd
 */
inline int cofsign (uint i, uint j) {
  return ( ((i+j)%2) ? -1 : 1 );
}

#endif

/**
 * Clamp a value to an upper bound.
 * 
 * @param Value The value to clamp.
 * @param Clamp The upper bound.
 */
inline int clamp_upper (int Value, int Clamp) {
  if (Value > Clamp) return Clamp;
  return Value;
}

/**
 * Clamp a value to a lower bound.
 * 
 * @param Value The value to clamp.
 * @param Clamp The lower bound.
 */
inline int clamp_lower (int x, int Clamp)
{
  if (x < Clamp) return Clamp;
  return x;
}

#endif // #ifndef _INLINES_HH_

--- NEW FILE: FDolly_Control.H ---
/* -*-C++-*- 

   "$Id: FDolly_Control.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
  
   Please report all bugs and problems to "flek-devel at sourceforge.net".
   
*/

#ifndef _FDOLLY_CONTROL_H_
#define _FDOLLY_CONTROL_H_

#include <Flek/FVector3.H>
#include <Flek/FMatrix4x4.H>

/**
 * @package libflek_gl
 * 
 * Class for a dolly controller.
 */
class FDolly_Control {

protected:
  
  // Current transformation matrix
  FMatrix4x4 mNow;

  bool Dragging;

  // Mouse translations/points
  double vNow, vDown;

  // Current dolly
  double dNow, dDown;

  // For scaling given coordinate value
  double scale_factor;
  
public:
  
  /**
   * Default constructor
   */
  FDolly_Control (double sf=1.0)
    : mNow(), Dragging(false), vNow(0), vDown(0), dNow(0), dDown(0),
      scale_factor(sf)
  {}
  
  /**
   * Copy constructor
   */
  FDolly_Control (const FDolly_Control& dc)
    : mNow(dc.mNow), Dragging(dc.Dragging), vNow(dc.vNow), vDown(dc.vDown),
      dNow(dc.dNow), dDown(dc.dDown), scale_factor(dc.scale_factor)
  {}
  
  /**
   * Destructor
   */
  ~FDolly_Control()
  {}
  
  FDolly_Control& operator = (const FDolly_Control& dc) // Assignment operator
  {
    mNow = dc.mNow; Dragging = dc.Dragging; vNow = dc.vNow; vDown = dc.vDown;
    dNow = dc.dNow; dDown = dc.dDown; scale_factor = dc.scale_factor;
    return (*this);
  }
  
  void reset (void) {
    dNow = 0.0; dDown = 0.0 ; mNow.reset();
  }
  
  void set_scale(double sf) {
    scale_factor = sf;
  }
  
  void reset_scale(void) {
    scale_factor = 1.0;
  }
  
  /**
   * Specify mouse position.
   */
  void mouse (const FVector3& pos) {
    // only z coordinate is used
    vNow = scale_factor*pos[2];
  }
  
  /**
   * Specify mouse position.
   */
  void mouse (double z) {
    vNow = scale_factor*z;
  }
  
  /**
   * Get the translation matrix.
   */
  FMatrix4x4 value (void) const {
    return mNow;
  }
  
  /**
   * Get the dolly value.
   */
  double dolly_value (void) const {
    return dNow;
  }
  
  /**
   * Get dolly value as FVector.
   */
  FVector3 dolly_vector (void) const {
    // dolly value is in z
    return FVector3(0,0,dNow);
  }
  
  /**
   * Begin a drag.
   */
  void begin_drag (void) {
    Dragging = true; vDown = vNow;
  }
  
  /**
   * End a drag.
   */
  void end_drag (void) {
    Dragging = false; dDown = dNow;
  }

  /**
   * Check dragging status
   */
  bool dragging (void) const {
    return Dragging;
  }
  
  /**
   * Update the FVectors and matrices.
   */
  void update (void) {
    if (Dragging) {
      dNow = dDown; dNow += vNow; dNow -= vDown;
      
      // Fill in transposed order for GL
      mNow[3][0] = 0.0;
      mNow[3][1] = 0.0;
      mNow[3][2] = dNow;
    }
  }
};

#endif

--- NEW FILE: FQuaternion.H ---
/* -*-C++-*- 

   "$Id: FQuaternion.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
  
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef __FQUATERNION_H__
#define __FQUATERNION_H__

#include <Flek/FBase.H>
#include <Flek/FVector3.H>
#include <Flek/FMatrix4x4.H>

/** @package libflek_core
 * The Quaternion class.
 */
class FQuaternion : public FBase
{
public:

  /**
   * Default constructor - create an identity quaternion
   */
  FQuaternion ()
    : FBase (), v (), w (1.0)
    {}

  /** 
   * Construct from a vector. Scalar is set to 0
   */
  FQuaternion (const FVector3& vec)
    : FBase (), v (vec), w (0.0)
    {}
  
  /**
   * Constructor from a vector and a scalar
   */
  FQuaternion (const FVector3& vec, double scalar)
    : FBase (), v (vec), w (scalar)
    {}

  /**
   * Same as above, but with reverse order
   */
  FQuaternion (double scalar, const FVector3& vec)
    : FBase (), v (vec), w (scalar)
    {}

  /**
   * Construct from 3/4 individual values. Scalar is set to 0 by default
   */
  FQuaternion (double x, double y, double z, double scalar=0.0)
    : FBase (), v (x, y, z), w (scalar)
    {}

  /**
   * Copy constructor
   */
  FQuaternion (const FQuaternion& quat)
    : FBase (quat), v (quat.v), w (quat.w)
    {}

  /**
   * Destructor
   */
  ~FQuaternion ()
    {}

  /**
   * Assignment operator
   */
  FQuaternion& operator = (const FQuaternion& quat)
    {
      FBase :: operator = (quat);
      v = quat.v; w = quat.w;
      return (*this);
    }

  /**
   * Assignment from FVector3
   */
  FQuaternion& operator = (const FVector3& vec)
    {
      v = vec; w = 0.0;
      return (*this);
    }
     
  /**
   * Set the vector and scalar parts of the quaternion
   */
  void set (const FVector3& vec, double scalar=0.0)
    {
      v = vec; w = scalar;
    }

  /**
   * Set the vector and scalar parts of the quaternion
   */
  void set (double x, double y, double z, double scalar=0.0)
    {
      v.set (x, y, z); w = scalar;
    }

  /**
   * Reset the quaternion to its default state - identity.
   */
  void reset (void)
    {
      v.reset (); w = 1.0;
    }

  /**
   *  Make a copy of the object implement FBase class pure virtual function
   */
  virtual FBase * copy (void) const
    {
      FQuaternion * quat = new FQuaternion (*this);
      return quat;
    }
  
  /**
   * Access the elements of the quaternion. Indices start at 0 and the
   *  scalar is at index=3
   */
  double& operator [] (uint index)
    {
      if ( index == 3 ) return w;
      return v[index];
    }
     
  double operator [] (uint index) const
    {
      if ( index == 3 ) return w;
      return v[index];
    }

  /**
   * Class member functions which return the identity quaternion
   * Identity quaternion is with the all vector components=0 and scalar=1
   */
  static FQuaternion identity(void)
    {
      FQuaternion ident;  // Default constructor creates an identity quaternion
      return ident;
    }

  /**
   * Class member functions which return the identity quaternion
   * Identity quaternion is with the all vector components=0 and scalar=1
   */     
  static FQuaternion I (void)
    {
      FQuaternion ident;  // Default constructor creates an identity quaternion
      return ident;
    }

  void operator += (const FQuaternion& quat)
    {
      w += quat.w;
      v += quat.v;
    }
  
  void operator -= (const FQuaternion& quat)
    {
      w -= quat.w;
      v -= quat.v;
    }
  
  void operator *= (const FQuaternion& quat)
    {
      FVector3 vec;
      double s;
      
      s   = w*quat.w - v*quat.v;
      vec = quat.v*w + v*quat.w + (v % quat.v);
      
      w = s; v = vec;
    }
  
  void operator *= (const FVector3& vec)
    {
      FQuaternion v2q (vec);
      
      this->operator *= (v2q);
    }
  
  void operator *= (double scalar)
    {
      w *= scalar;
      v *= scalar;
    }
  
  void operator /= (double scalar)
    {
      w /= scalar;
      v /= scalar;
    }
  
  /**
   * Square of the length of a quaternion
   */
  friend double lengthsqr(const FQuaternion& quat)
    {
      double lensqr = quat.v*quat.v + quat.w*quat.w;
      return lensqr;
    }
  
  /**
   * Length of a quaternion
   */
  friend double length(const FQuaternion& quat)
    {
      return sqrt(lengthsqr(quat));
    }
  
  /**
   * For consistency define norm and normsqr also
   */
  friend double normsqr(const FQuaternion& quat)
    {
      return lengthsqr(quat);
    }

  friend double norm(const FQuaternion& quat)
    {
      return length(quat);
    }
  
  /**
   * Compute conjugate of this quaternion which -v,s
   */
  friend FQuaternion conjugate(const FQuaternion& quat)
    {
      return FQuaternion(-quat.v,quat.w);
    }
  
  /**
   * Normalize a quaternion - make it a unit quaternion
   * Returns the original length of the quaternion
   * If length is 0, nothing is changed
   */
  friend double normalize(FQuaternion& quat)
    {
      double len = length(quat);
      if ( is_non_zero(len) == true )
	quat /= len;
      return len;
    }

  friend FQuaternion normalized(const FQuaternion& quat)
    {
      FQuaternion unitq = quat;
      normalize(unitq);
      return unitq;
    }

  /**
   * Negation
   */
  friend FQuaternion operator - (const FQuaternion& q)
    {
      FQuaternion neg(-q.w, -q.v);
      return neg;
    }
  
  friend FQuaternion operator + (const FQuaternion& q1, const FQuaternion& q2)
    {
      FQuaternion sum = q1;
      sum += q2;
      return sum;
    }
  
  friend FQuaternion operator - (const FQuaternion& q1, const FQuaternion& q2)
    {
      FQuaternion diff = q1;
      diff -= q2;
      return diff;
    }
  
  /**
   * Post-multiplication by a scalar
   */
  friend FQuaternion operator * (const FQuaternion& q, double scalar)
    {
      FQuaternion prod = q;
      prod *= scalar;
      return prod;
    }
  
  /**
   * Pre-multiplication by a scalara
   */
  friend FQuaternion operator * (double scalar, const FQuaternion& q)
    {
      FQuaternion prod = q;
      prod *= scalar;
      return prod;
    }

  /** 
   * Division by a scalar
   */
  friend FQuaternion operator / (const FQuaternion& q, double scalar)
    {
      FQuaternion quot = q;
      quot /= scalar;
      return quot;
    }
  
  /**
   * Multiplication of 2 quaternions
   */
  friend FQuaternion operator * (const FQuaternion& q1, const FQuaternion& q2)
    {
      FQuaternion prod = q1;
      prod *= q2;
      return prod;
    }

  /**
   * Post-multiplication of a quaternion by a FVector3
   * Same as above, except FVector3 is promoted to quaternion with 
   * scalar value 0.0
   */
  friend FQuaternion operator * (const FQuaternion& q, const FVector3& v)
    {
      FQuaternion prod = q;
      prod *= v;
      return prod;
    }
  
  /**
   * Pre-multiplication of a quaternion by a FVector3
   */
  friend FQuaternion operator * (const FVector3& v, const FQuaternion& q)
    {
      FQuaternion prod = q;
      prod *= v;
      return prod;
    }

  /**
   * Convert to a rotation matrix. Assumes that quaternion has been normalized
   */
  FMatrix3x3 to_matrix(void) const
    {
      FMatrix3x3 mat;
      double x,y,z,s;
      
      v.get(x,y,z); s = w;
      
      mat[0].set( 1.0 - 2.0*(y*y + z*z), 2.0*(x*y - s*z), 2.0*(x*z + s*y) );
      mat[1].set( 2.0*(x*y + s*z), 1.0 - 2.0*(x*x + z*z), 2.0*(y*z - s*x) );
      mat[2].set( 2.0*(x*z - s*y), 2.0*(y*z + s*x), 1.0 - 2.0*(x*x + y*y) );
      
      return mat;
    }
  
  FMatrix4x4 to_matrix4(void) const
    {
      FMatrix4x4 mat4 = to_matrix();
      mat4[3][3] = 1.0;
      return mat4;
    }
  
  void to_matrix(double array[16]) const
    {
      // Similar to toMatrix4, but fills a given array of 16 elements with the
      // rotation matrix corresponding to this quaternion in column major form
      FMatrix4x4 mat4 = to_matrix4();
      mat4.fill_array_column_major(array);
    }
     
  friend FMatrix3x3 to_matrix(const FQuaternion& quat)
    {
      return quat.to_matrix();
    }
  
  friend FMatrix4x4 to_matrix4(const FQuaternion& quat)
    {
      return quat.to_matrix4();
    }
  
  //--- Conversion to and from axis and angle ---
  //--- All angles are specified in radians ---
  
  /**
   * Get the angle of rotation. Returns value between 0 and PI
   */
  double get_angle(void) const
    {
      return 2.0 * acos(w);
    }
  
  /**
   * Get the angle of rotation. Returns value between 0 and PI
   * Computes angle after normalizing the quaternion
   */
  friend double get_angle(const FQuaternion& quat)
    {
      // Make the quaternion a unit quaternion first
      FQuaternion nq = normalized(quat);
      
      return nq.get_angle();
    }
     
  /**
   *  Get the axis of rotation. Returns unit axis
   */
  friend FVector3 get_axis(const FQuaternion& quat)
    {
      // Make the quaternion a unit quaternion first
      FQuaternion nq = normalized(quat);
      
      FVector3 axis = normalized(nq.v);
      return axis;
    }
     
  /**
   * Get the axis and angle.
   */
  void get_axis_and_angle(FVector3& axis, double& theta) const
    {
      FQuaternion nq = normalized(*this);
      
      theta = 2.0 * acos(nq.w);
      axis = normalized(nq.v);
    }
  
  /**
   * Set the axis and angle.
   */
  void set_axis_and_angle(const FVector3& axis, double theta)
    {
      w = cos(theta/2.0);
      v = normalized(axis);
      v *= sin(theta/2.0);
    }

  /**
   * Change the angle to a new value. Use same axis as before
   */
  void set_angle(double theta)
    {
      w = cos(theta/2.0);
      normalize(v);
      v *= sin(theta/2.0);
    }
  
  /**
   * Scale the angle by the given scale factor
   */
  void scale_angle(double scale_factor)
    {
      set_angle(get_angle()*scale_factor);
    }
  
  /**
   * Insertion and extraction operators
   */
  friend ostream& operator << (ostream& o, const FQuaternion& quat)
    {
      o << "{ " << quat.v << "," << quat.w << " }";
      return o;
    }

  /**
   * Insertion and extraction operators
   */  
  friend istream& operator >> (istream& i, FQuaternion& quat)
    {
      char c;
      i >> c >> quat.v >> c >> quat.w >> c;
      return i;
    }

protected:

  /**
   * Vector component
   */
  FVector3 v;
  
  /**
   * Scalar component
   */
  double w;

};

#endif // #ifndef FQuaternion_H_

--- NEW FILE: FSocket.H ---
/* -*-C++-*- 

   "$Id: FSocket.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1997 GARRET.
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// FSocket was adapted from K.A. Knizhnik's very nice SAL library.

#ifndef __FSOCKET_H__
#define __FSOCKET_H__

#include <time.h>

#define DEFAULT_CONNECT_MAX_ATTEMPTS 100
#define DEFAULT_RECONNECT_TIMEOUT    1  // seconds
#define DEFAULT_LISTEN_QUEUE_SIZE    5
#define LINGER_TIME                  10 // seconds
#define WAIT_FOREVER                 ((time_t)-1)

#if defined(_WIN32) && !defined(__CYGWIN__)
typedef HANDLE descriptor_t; 
#else
typedef int descriptor_t; 
#endif

/**
 * @package libflek_core
 * FSocket is an abstract socket interface.  
 * FSocket was adapted from K.A. Knizhnik's very nice SAL library.
 * It provides a socket implementation based on the socket library
 * provided by the operating system.  As local sockets are not supported 
 * under Win32, shared memory and semaphore objects are used to provide
 * high speed communications on the same computer.
 */
class FSocket { 
 public: 
  virtual int read(void* buf, size_t min_size, size_t max_size,
		   time_t timeout = WAIT_FOREVER) = 0;
  
  /**
   * Read data from socket.
   * @param buf Buffer to hold fetched data.
   * @param buf_size Number of bytes to fetch.
   * @return 1 if operation successfully completed, 0 otherwise. 
   */
  virtual int read(void* buf, size_t size) = 0;

  /**
   * Write data to socket.
   * @param buf Buffer that contains the data to be sent.
   * @param buf_size Number of bytes to send.
   * @return 1 if operation successfully completed, 0 otherwise.
   */
  virtual int write(void const* buf, size_t size) = 0;
  
  /**
   * Check the status of the last operation with socket. 
   * @return 1 if the last operation completed successfully, 0 otherwise.
   */
  virtual int valid() = 0; 
  
  /**
   * Get error message text for the last operation. 
   * @param buf Buffer to receive text of the error message.
   * @param buf_size Size of buffer, no more than buf_size bytes will be 
   * placed in the buffer.
   */
  virtual void get_error_text(char* buf, size_t buf_size) = 0;

  /**
   * Accept new socket. This method is called by server to establish a
   * connection with the new client. When the client executes a connect 
   * method to the access server's accept port, accept method will create 
   * new socket, which can be used for communication with the client. 
   * The accept method will block the current task until some connection 
   * is established. 
   * @return Pointer to new socket or NULL if operation failed.
   */
  virtual FSocket* accept() = 0;
  
  /**
   * Cancel accept operation. Task blocked in accept call is woken
   * and execution continues.
   * @return 1 if socket was successfully closed, 0 otherwise.
   */
  virtual int cancel_accept() = 0;
  
  /**
   * Shutdown the socket. This function prohibits write and read 
   * operation on the socket. All further attempts to read or write 
   * data from/to the socket will be denied.  But all previously 
   * initiated operations are guaranteed to be completed. 
   * @return 1 if operation successfully completed, 0 otherwise. 
   */
  virtual int shutdown() = 0;
  
  /**
   * Close socket connection.
   * @return 1 if operation successfully completed, 0 otherwise.
   */
  virtual int close() = 0;
  
  enum socket_domain { 
    sock_any_domain,   // domain is chosen automatically
    sock_local_domain, // local domain (i.e. Unix domain socket) 
    sock_global_domain // global domain (i.e. INET sockets) 
  };

  /**
   * Establish connection with server. This method will do at most 
   * max_attempts attempts to connect server, with timeout interval 
   * between attempts.
   * @param address Address of server socket in format "hostname:port".
   * @param domain Type of connection. The following values of this 
   * parameter are recognized:
   * <ul>
   *   <li><b>sock_any_domain</b> = domain is chosen automatically.</li>
   *   <li><b>sock_local_domain</b> = local domain (connection with one host).</li>
   *   <li><b>sock_global_domain</b> = internet domain.</li>
   * </ul>
   * If sock_any_domain is specified, local connection is chosen when 
   * either port was omitted in specification of the address or hostname 
   * is "localhost", and global connection is used in all other cases. 
   * @param max_attempts Maximal number of attempts to connect to server.
   * @param timeout Timeout in seconds between attempts to connect the server.
   * @return This method always create new socket object and returns a 
   * pointer to it. If connection with server was not established, this 
   * socket contains error code describing reason of failure.  So returned 
   * socket should be first checked by the valid() method. 
   */
  static FSocket* connect(char const* address, 
			   socket_domain domain = sock_any_domain, 
			   int max_attempts = DEFAULT_CONNECT_MAX_ATTEMPTS,
			   time_t timeout = DEFAULT_RECONNECT_TIMEOUT);
  
  /**
   * Create and open socket in local domain at the server site. 
   * @param address Address to be assigned to the socket. 
   * @param listen_queue_size Size of listen queue.
   * @return This method always create new socket object and returns 
   * pointer to it. If socket can not be opened, error code field of 
   * returned socket describes the reason of failure. So returned
   * socket should be first checked by the valid() method. 
   */
  static FSocket* create_local(char const* address,
				int listen_queue_size = 
				DEFAULT_LISTEN_QUEUE_SIZE);
  
  /**
   * Create and open socket in global (internet) domain at the server site.
   * @param address Address to be assigned to the socket.
   * @param listen_queue_size Size of listen queue.
   * @return This method always create new socket object and returns 
   * pointer to it. If socket can not be opened, error code field of 
   * returned socket describes the reason of failure. So returned
   * socket should be first checked by the valid() method. 
   */
  static FSocket* create_global(char const* address,
				 int listen_queue_size = 
				 DEFAULT_LISTEN_QUEUE_SIZE);
  
  virtual ~FSocket() {} 
  FSocket() { state = ss_close; }
  
 protected:
  enum { ss_open, ss_shutdown, ss_close } state;
};

// 
// Return current host name + identifier of current process
//
extern char const* get_process_name(); 

#endif


--- NEW FILE: FFile.H ---
/* -*-C++-*- 

   "$Id: FFile.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
  
   Please report all bugs and problems to "flek-devel at sourceforge.net".
   
*/

#ifndef _FFILE_H_
#define _FFILE_H_

#include <stdio.h>

typedef unsigned long ulong;
typedef unsigned long * ulongPtr;
typedef unsigned short ushort;
typedef unsigned short * ushortPtr;
typedef unsigned char uchar;
typedef unsigned char * ucharPtr;

enum FFileMode {
  FFileNull = 0,
  FFileRead = 1,
  FFileReadPlus,
  FFileWrite,
  FFileWritePlus,
  FFileAppend,
  FFileAppendPlus
};

/** @package libflek_core
 * fFile provides efficient file io routines in a c++ encapsulation.  
 * On most systems it should perform better than c++ io streams.
 * Ultimately, this class should be similar to Ruby's
 * <a href="http://www.ruby-lang.org/en/man-1.4/File.html">File Class</a>.
 */
class FFile {

 public:

  /**
   * The Constructor.
   *
   * @param filename The name of the file to open.
   * @param mode The mode the file should be opened in:
   * <ul>
   * <li><b>FFileRead</b> - Open  text  file  for reading.  The stream is 
   *     positioned at the beginning of the file.</li>
   * <li><b>FFileReadPlus</b> - Open for reading and writing.  The stream is 
   *     positioned at the beginning of the file.</li>
   * <li><b>FFileWrite</b> - Truncate file to zero length or create text file
   *     for writing.   The stream is positioned at the
   *     beginning of the file.</li>
   * <li><b>FFileWritePlus</b> - Open  for reading and writing.  The file is created
   *     if it does not exist, otherwise  it  is  truncated.
   *     The  stream  is  positioned at the beginning of the file.</li>
   * <li><b>FFileAppend</b> - Open for writing.  The file is created if  it  does
   * not  exist.  The stream is positioned at the end of the file.</li>
   * <li><b>FFileAppendPlus</b> - Open for reading and writing.  The file is  created
   * if  it does not exist.  The stream is positioned at
   * the end of the file.</li>
   *</ul>
   */
  FFile (char *filename=0, FFileMode mode=FFileRead) {
    Fd = 0;
    Error = 0;
    
    if (filename)
      open (filename, mode);
  }

  /**
   * The destructor closes the file if it is still open.
   */
  ~FFile () {
    if (Fd)
      fclose (Fd);
  }

  /**
   * Open a file with the given filename, and a mode.  The mode should be 
   * one of the standard fopen modes (see the constructor for a listing).
   */
  void open (char *filename, FFileMode mode);

  /**
   * Put a single character into the file stream using Hi (MSB) byte order.
   */
  inline void put_hi (char c) {
    fputc (c, Fd);
  }

  /**
   * Put a single unsigned character into the file stream using Hi (MSB) byte order.
   */
  inline void put_hi (uchar c) {
    fputc (c, Fd);
  }

  /**
   * Put a single unsigned short into the file stream using Hi (MSB) byte order.
   */
  inline void put_hi (unsigned short c) {
    unsigned char t[2];
    t[0] = ((c >> 8) & 0xff);
    t[1] = (c & 0xff);
    int size = fwrite (t, 2, 1, Fd);
    if (size != 1) Error = 1;
  }

  /**
   * Put a single unsigned short into the file stream using Hi (MSB) byte order.
   */
  inline void put_hi (short c) {
    put_hi ((unsigned short) c);
  }
  
  /**
   * Put a single unsigned long into the file stream using Hi (MSB) byte order.
   */
  inline void put_hi (unsigned long c) {
    unsigned char t[4];
    t[0] = (unsigned char)((c >> 24) & 0xff);
    t[1] = (unsigned char)((c >> 16) & 0xff);
    t[2] = (unsigned char)((c >> 8) & 0xff);
    t[3] = (unsigned char)(c & 0xff);
    int size = fwrite (t, 1, 4, Fd);
    if (size != 4) Error = 1;
  }

  /**
   * Put a single long into the file stream using Hi (MSB) byte order.
   */
  inline void put_hi (long c) {
    unsigned char t[4];
    t[0] = (unsigned char)((c >> 24) & 0xff);
    t[1] = (unsigned char)((c >> 16) & 0xff);
    t[2] = (unsigned char)((c >> 8) & 0xff);
    t[3] = (unsigned char)(c & 0xff);
    int size = fwrite (t, 1, 4, Fd);
    if (size != 4) Error = 1;
  }

  /**
   * Write an array of characters into the file stream.
   */
  inline void write (char *c, int len) {
    int size = fwrite ((void *)c, 1, len, Fd);
    if (size != len) Error = 1;
  }

  /**
   * Get a single unsigned character from the file stream using Hi (MSB) byte order.
   */
  void get_hi (uchar& r) { 
    fread (&r, 1, 1, Fd);
  } 

  /**
   * Get a single short int from the file stream using Hi (MSB) byte order.
   */
  void get_hi (short& r) { 
    uchar b[2];
    fread (b, 2, 1, Fd);
    r = ((b[0] << 8) | b[1]); 
  } 

  /**
   * Get a single unsigned short int from the file stream using Hi (MSB) byte order.
   */
  void get_hi (ushort& r) { 
    uchar b[2];
    fread (b, 2, 1, Fd);
    r = ((b[0] << 8) | b[1]); 
  } 

  /**
   * Get a single unsigned long int from the file stream using Hi (MSB) byte order.
   */
  void get_hi (ulong& r) { 
    uchar b[4];
    fread (b, 4, 1, Fd);
    r = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); 
  } 

  /**
   * Read an array of characters into the file stream.
   */
  inline void read (char *c, int len) {
    int size = fread ((void *)c, 1, len, Fd);
    if (size != len) Error = 1;
  }
  
  /**
   * Read an array of unsigned characters into the file stream.
   */
  inline void read (uchar *c, int len) {
    int size = fread ((void *)c, 1, len, Fd);
    if (size != len) Error = 1;
  }

  /**
   * Set the file postion indicator to pos.  Seek can set pos relative to
   * the beginning (mode=SEEK_SET), the end (mode=SEEK_END), or the current
   * position (mode=SEEK_CUR).
   */
  inline void seek (long pos, int mode = SEEK_SET) {
    Error = fseek (Fd, pos, mode);
  }

  /**
   * Report the current file position.
   */
  long tell () {
    long rval = ftell (Fd);
    if (rval == -1) Error = -1;
    return rval;
  }

  /** 
   * Report if there has been any errors.
   */
  bool bad () {
    if (Error == 0) return false;
    return true;
  }
  
  /**
   * Close the file stream.
   */
  void close () {
    fclose (Fd);
    Fd = 0;
  }
  
  /**
   * Return the C file handle.
   */
  FILE *fd () {
    return Fd;
  }

  char* expand (char* name);
  
protected:

  FILE *Fd;
  char *filename;
  int Error;

};

/**
 * Convert an array of MSB longs to an array of LSB longs.
 */
void lo_to_hi (ulong *buffer, int len);

#endif

--- NEW FILE: Flve_Check_Button.H ---
//	======================================================================
//	File:    Flve_Check_Button.h - Flve_Check_Button implementation
//	Library: flvw - FLTK Widget
//	Version: 0.1.0
//	Started: 01/12/2000
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	Flve_Check_Button implements a toggle editor for a list/table
//
// 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 FLVE_CHECK_BUTTON_H
#define FLVE_CHECK_BUTTON_H

#include <FL/Fl_Check_Button.H>
#include <Flek/Flv_List.H>
#include <stdio.h>

class Flve_Check_Button : public Fl_Check_Button
{
public:
	Flve_Check_Button( int X, int Y, int W, int H, const char *l=0 ) :
		Fl_Check_Button(X,Y,W,H,l) {	owner=NULL;	};
	Fl_Widget *owner;
protected:
	int handle(int event );
};

void draw_flve_check_button( int X, int Y, int W, int H,
															Flve_Check_Button *b, char *v );
#endif

--- NEW FILE: gl.H ---
/* -*-c++-*- 

   "$Id: gl.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FGL_H_
#define _FGL_H_

#include <Flek/FVector2.H>
#include <Flek/FVector3.H>
#include <Flek/FVector4.H>
#include <Flek/FMatrix4x4.H>
#include <Flek/FMatrix3x3.H>
#include <Flek/FArcball_Control.H>
#include <Flek/FImage.H>

#include <GL/gl.h>
#include <FL/gl.h>

/** @package libflek_gl
 * Multiply the current GL matrix by the fMatrix M. 
 * This function is a wrapper around the GL function,
 * glMultMatrixd.
 */
void glMultMatrix (const FMatrix4x4& M);

/** 
 * Multiply the current GL matrix by an arcball rotation 
 * matrix.
 */
inline void glMultMatrix (const FArcball_Control& a)
{
  glMultMatrix (a.value ());
}

/**
 * glVertex is used within glBegin - glEnd pairs to specify point, 
 * line, and polygon vertices.  This form takes an fVector4 as
 * it's argument.
 */
inline void glVertex (const FVector4& v)
{
  glVertex4d (v[0], v[1], v[2], v[3]);
}

/**
 * This form of glVertex takes an fVector3 as it's argument.
 */
inline void glVertex (const FVector3& v)
{
  glVertex3d (v[0], v[1], v[2]);
}

/**
 * This form of glVertex takes an fVector2 as it's argument.
 */
inline void glVertex (const FVector2& v)
{
  glVertex2d (v[0], v[1]);
}

/**
 * This form of glVertex takes 4 doubles as it's arguments.
 */
inline void glVertex (const double& x, const double& y, const double& z, const double& w)
{
  glVertex4d (x, y, z, w);
}

/**
 * This form of glVertex takes 3 doubles as it's arguments.
 */
inline void glVertex (const double& x, const double& y, const double& z)
{
  glVertex3d (x, y, z);
}

/**
 * This form of glVertex takes 2 doubles as it's arguments.
 */
inline void glVertex (const double& x, const double& y)
{
  glVertex2d (x, y);
}

/**
 * glColor is used to specify the current color. 
 * This form takes an fVector4 as it's argument (RGBA).
 */
inline void glColor (const FVector4& v)
{
  glColor4d (v[0], v[1], v[2], v[3]);
}

/**
 * This form takes an fVector3 as it's argument (RGB).
 */
inline void glColor (const FVector3& v)
{
  glColor3d (v[0], v[1], v[2]);
}

/**
 * This form takes 4 doubles as it's arguments (RGBA).
 */
inline void glColor (const double& x, const double& y, const double& z, const double& w)
{
  glColor4d (x, y, z, w);
}

/**
 * This form takes 3 doubles as it's arguments (RGB).
 */
inline void glColor (const double& x, const double& y, const double& z)
{
  glColor3d (x, y, z);
}

/**
 * glNormal is used to specify the current normal. 
 * This form takes an fVector4 as it's argument.
 * It ignores the w, or 4th term in the fVector4.
 */
inline void glNormal (const FVector4& v)
{
  glNormal3d (v[0], v[1], v[2]);
}

/**
 * This form takes an fVector3 as it's argument.
 */
inline void glNormal (const FVector3& v)
{
  glNormal3d (v[0], v[1], v[2]);
}

/**
 * This form takes an fVector2 and a z value as it's arguments.
 */
inline void glNormal (const FVector2& v, const double &z)
{
  glNormal3d (v[0], v[1], z);
}

/**
 * This form takes 3 doubles as it's arguments.
 */
inline void glNormal (const double& x, const double& y, const double& z)
{
  glNormal3d (x, y, z);
}

/**
 * glScale scales the current transforamtion matrix by
 * an x, y and z scale component.
 * This form takes an fVector3 as it's argument.
 */
inline void glScale (const FVector3& v)
{
  glScaled (v[0], v[1], v[2]);
}

/**
 * This form takes 3 doubles as it's argument.
 */
inline void glScale (const double &x, const double &y=1, const double &z=1)
{
  glScaled (x, y, z);
}

/**
 * glTranslate translates the current transforamtion matrix by
 * an x, y and z translation component.
 * This form takes an fVector3 as it's argument.
 */
inline void glTranslate (const FVector3& v)
{
  glTranslated (v[0], v[1], v[2]);
}

/**
 * This form takes 3 doubles as it's arguments.
 */
inline void glTranslate (const double &x, const double &y=0, const double &z=0)
{
  glTranslated (x, y, z);
}

/**
 * glRotate rotates the current transformation matrix by an angle a about an axis v.
 */
inline void glRotate (const double &a, const FVector3 &v)
{
  glRotated (a, v[0], v[1], v[2]);
}

/**
 * glRotate rotates the current transformation matrix by an angle a about an axis (x, y, z).
 */
inline void glRotate (const double &a, const double &x, const double &y, const double &z)
{
  glRotated (a, x, y, z);
}

/**
 * This function loads an image for texturing in OpenGL.
 */
inline void glTexImage2D (FImage* img, GLenum target=GL_TEXTURE_2D, GLint level=0)
{
  glTexImage2D (target,
                level,
                4,
                img->width (),
                img->height (),
                0,
                GL_RGBA,
                GL_UNSIGNED_BYTE,
                (GLvoid *)(*img->begin()) );
}

#endif

--- NEW FILE: Fl_App_Window.H ---
/* -*-C++-*- 

   "$Id: Fl_App_Window.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FL_APP_WINDOW_H_
#define _FL_APP_WINDOW_H_

#include <FL/Fl_Widget.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Pack.H>

#include <Flek/Fl_Dockable_Window.H>
#include <Flek/export.h>

/** @package libflek_ui
 * Fl_App_Window is a window that can have Fl_Dockable_Windows
 * "docked" either vertically or horizontally to the contents of the window.
 * An Fl_App_Window starts with a top-level "application" window.
 * Flek creates an Fl_Pack group that fills the application window.
 * The pack group contains the child "contents" window and any
 * "docked" groups.
 * You might think of the contents window as the "client" area of the application.
 */
class FLEK_UI_API Fl_App_Window : public Fl_Window {
private:
  /**
   * Holds the contents window and any docked windows.
   */
  Fl_Pack* _pack;

  /**
   * Provides the "client" area of the application window.
   */
  Fl_Window* _contents;

  /**
   * Holds a list of pointers to dockable windows that have permission to
   * dock to this window.
   * This is also used to provide automatic showing and hiding of undocked
   * windows when the application windows is shown/hid.
   */
  Fl_Dockable_Window** dockable_windows;

  /**
   * Specifies the capacity of the dockable_windows list.
   */
  int dockable_windows_capacity;

  /**
   * Tracks the number of elements used in the dockable_windows list.
   */
  int dockable_windows_size;

  /**
   * Helps the constructors do window creation.
   */
  void create_app_window(int w, int h, const char* l);

protected:
  virtual void flush();

public:
  /**
   * Constructs an Fl_App_Window.
   */
  Fl_App_Window(int w, int h, const char *l = 0);

  /**
   * Constructs an Fl_App_Window, forcing a specific position.
   * This probably isn't what you want.  Try the other constructor instead.
   */
  Fl_App_Window(int x, int y, int w, int h, const char *l = 0);

  ~Fl_App_Window();
  
  /**
   * Returns a pointer to the Fl_Pack group, which contains the contents window
   * and any docked groups.
   * From what I can tell, this is only used by the docking sample.
   */
  Fl_Pack* tpack() { return _pack; }

  /**
   * Returns a pointer to the contents window.
   */
  Fl_Window* contents() { return _contents; }

  /**
   * Sets the box type and color for the contents window.
   * Includes uchar signatures to keep fluid happy.
   */
  void box(Fl_Boxtype b) { _contents->box(b); }
  void color(Fl_Color a) { _contents->color(a); }
// CET - FIXME  void color(Fl_Color a, Fl_Color b) { _contents->color(a); , b); }
//  void color(uchar a) { _contents->color(a); }
//  void color(uchar a, uchar b) { _contents->color(a, b); }

  /**
   * Adds the widget to the contents window.
   */
  void add(Fl_Widget *w);

  /**
   * Repacks the window.  Used after resizing or adding dockable windows.
   */
  void repack();
  
  /**
   * Resizes the contents window.
   */
  void resize(int x, int y, int w, int h);
  
#ifdef FLEK_FLTK_2
  void layout();
#endif  
  
  /**
   * Grants permission for the dockable window to dock to this window.
   * This does not cause the dockable window to be docked to this window.
   */  
  void accept_dockable(Fl_Dockable_Window* W);

  /**
   * Determines if a dockable window has permission to dock to this window.
   */  
  bool may_dock(Fl_Dockable_Window* W);
  
  /**
   * Docks the dockable window to this window, adding it to the specified
   * position in the pack group.
   * This also grants permission for the dockable window to dock
   * to this window.
   * Docking an Fl_Dockable_Window to an Fl_App_Window does not change
   * the size of the Fl_App_Window.  Rather, the size of the contents
   * window is adjusted to accomodate the Fl_Dockable_Window.
   */
  void add_dockable(Fl_Dockable_Window* W, int position = 0);

  /**
   * Begin adding widgets to the contents window.
   */
  void begin() { Fl_Group::current(_contents); }

  /**
   * Shows or hides the application window.
   */
  void show();
  void hide();

  int handle(int);
};

#endif

--- NEW FILE: Fl_Stock.H ---
/* -*-C++-*- 

   "$Id: Fl_Stock.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FL_STOCK_H_
#define _FL_STOCK_H_

#include <FL/Fl_Button.H>
#include <Flek/export.h>

// Values used to align the text in the widget.

#ifndef FLEK_FLTK_2
#include <FL/Fl_Pixmap.H>
#define Fl_Flags int
#define Fl_Image Fl_Pixmap
#define FL_INACTIVE 4096
#endif

#define FL_TEXT_ALIGN_LEFT   0x00100000
#define FL_TEXT_ALIGN_RIGHT  0x00200000
#define FL_TEXT_ALIGN_TOP    0x00400000
#define FL_TEXT_ALIGN_BOTTOM 0x00800000

/** @package libflek_ui
 * The base class from which all stock buttons are derived.
 * These include:
 * 
 * Fl_Stock_Button_Ok, Fl_Stock_Button_Cancel,<br>
 * Fl_Stock_Button_Yes, Fl_Stock_Button_No,<br>
 * Fl_Stock_Button_Apply, Fl_Stock_Button_Close,<br>
 * Fl_Stock_Button_Add, Fl_Stock_Button_Remove,<br>
 * Fl_Stock_Button_New, Fl_Stock_Button_Previous,<br>
 * Fl_Stock_Button_Left, Fl_Stock_Button_Next,<br>
 * Fl_Stock_Button_Right, Fl_Stock_Button_Up,<br>
 * Fl_Stock_Button_Down, Fl_Stock_Button_Top,<br>
 * Fl_Stock_Button_Bottom, Fl_Stock_Button_Clear,<br>
 * Fl_Stock_Button_Open, Fl_Stock_Button_Copy,<br>
 * Fl_Stock_Button_Cut, Fl_Stock_Button_Exec,<br>
 * Fl_Stock_Button_First, Fl_Stock_Button_Help,<br>
 * Fl_Stock_Button_Last, Fl_Stock_Button_Save,<br>
 * Fl_Stock_Button_Search and Fl_Stock_Button_Search_Replace.
 *<p><img src="Fl_Stock_Button.png">
 */
class Fl_Stock_Button : public Fl_Button
{
public:
  /**
   * The constructor.  Passing a label to a stock button is usually
   * ignored.
   */
  Fl_Stock_Button (int,int,int,int,const char * = 0);
  void draw_label(int X, int Y, int W, int H, Fl_Color c, Fl_Flags f);
  void draw ();
#ifndef FLEK_FLTK_2
protected:
  Fl_Pixmap * image() { return image_; }
  void image (Fl_Pixmap*p) {image_ = p; }
  Fl_Pixmap *image_;
  void set_flag (int f) {flags_ |= f; Fl_Widget::set_flag(f);}
  void clear_flag (int f) {flags_ &= ~f; Fl_Widget::clear_flag(f);}
  int flags () {return (Fl_Widget::flags() | flags_); }
  int flags_;
#endif
};

class FLEK_UI_API Fl_Stock_Button_Ok : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Ok (int,int,int,int,const char*l="Ok");
};

class FLEK_UI_API Fl_Stock_Button_Cancel : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Cancel (int,int,int,int,const char*l="Cancel");
};

class FLEK_UI_API Fl_Stock_Button_Yes : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Yes (int,int,int,int,const char*l="Yes");
};

class FLEK_UI_API Fl_Stock_Button_No : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_No (int,int,int,int,const char*l="No");
};

class FLEK_UI_API Fl_Stock_Button_Apply : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Apply (int,int,int,int,const char*l="Apply");
};

class FLEK_UI_API Fl_Stock_Button_Close : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Close (int,int,int,int,const char*l="Close");
};

class FLEK_UI_API Fl_Stock_Button_Add : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Add (int,int,int,int,const char*l="Add");
};

class FLEK_UI_API Fl_Stock_Button_Remove : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Remove (int,int,int,int,const char*l="Remove");
};

class FLEK_UI_API Fl_Stock_Button_New : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_New (int,int,int,int,const char*l="New");
};

class FLEK_UI_API Fl_Stock_Button_Previous : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Previous (int,int,int,int,const char*l="Previous");
};

class FLEK_UI_API Fl_Stock_Button_Next : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Next (int,int,int,int,const char*l="Next");
};

class FLEK_UI_API Fl_Stock_Button_Left : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Left (int,int,int,int,const char*l="Left");
};

class FLEK_UI_API Fl_Stock_Button_Right : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Right (int,int,int,int,const char*l="Right");
};

class FLEK_UI_API Fl_Stock_Button_Up : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Up (int,int,int,int,const char*l="Up");
};

class FLEK_UI_API Fl_Stock_Button_Down : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Down (int,int,int,int,const char*l="Down");
};

class FLEK_UI_API Fl_Stock_Button_Top : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Top (int,int,int,int,const char*l="Top");
};

class FLEK_UI_API Fl_Stock_Button_Bottom : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Bottom (int,int,int,int,const char*l="Bottom");
};

class FLEK_UI_API Fl_Stock_Button_Clear : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Clear (int,int,int,int,const char*l="Clear");
};

class FLEK_UI_API Fl_Stock_Button_Open : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Open (int,int,int,int,const char*l="Open");
};

class FLEK_UI_API Fl_Stock_Button_Copy : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Copy (int,int,int,int,const char*l="Copy");
};

class FLEK_UI_API Fl_Stock_Button_Cut : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Cut (int,int,int,int,const char*l="Cut");
};

class FLEK_UI_API Fl_Stock_Button_Exec : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Exec (int,int,int,int,const char*l="Exec");
};

class FLEK_UI_API Fl_Stock_Button_First : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_First (int,int,int,int,const char*l="First");
};

class FLEK_UI_API Fl_Stock_Button_Help : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Help (int,int,int,int,const char*l="Help");
};

class FLEK_UI_API Fl_Stock_Button_Last : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Last (int,int,int,int,const char*l="Last");
};

class FLEK_UI_API Fl_Stock_Button_Save : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Save (int,int,int,int,const char*l="Save");
};

class FLEK_UI_API Fl_Stock_Button_Save_As : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Save_As (int,int,int,int,const char*l="Save As");
};

class FLEK_UI_API Fl_Stock_Button_Search : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Search (int,int,int,int,const char*l="Search");
};

class FLEK_UI_API Fl_Stock_Button_Search_Replace : public Fl_Stock_Button
{
  public:
  Fl_Stock_Button_Search_Replace (int,int,int,int,const char*l="Search and Replace");
};

#endif

--- NEW FILE: Fl_Toggle_Tree.H ---
/* -*-C++-*- 

   "$Id: Fl_Toggle_Tree.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FL_TOGGLE_TREE_H_
#define _FL_TOGGLE_TREE_H_

#include <Flek/Fl_Toggle_Tree_Base.H>
#include <Flek/Fl_Toggle_Node.H>
#include <FL/Fl_Pixmap.H>


enum Fl_ToggleState {
  FL_TOGGLE_NONE = 0,
  FL_TOGGLE_SELECT = 1,
  FL_TOGGLE_RESELECT = 2,
  FL_TOGGLE_SELECT_MASK = 3,
  FL_TOGGLE_OPENED = 4,
  FL_TOGGLE_CLOSED = 8,
  FL_TOGGLE_HIT = 16
};

class Fl_Input;

/** @package libflek_ui
 * Fl_Toggle_Tree is a tree widget that allows branch visibility to 
 * be toggled on and off, similar to a collapsible list widget that is 
 * found in most widget tool kits. 
 * <p><img src="Fl_Toggle_Tree.png">
 */
class Fl_Toggle_Tree : public Fl_Toggle_Tree_Base {

public:
  /**
   * The constructor makes an empty Fl_Toggle_Tree. 
   */
  Fl_Toggle_Tree(int x, int y, int w, int h);
  virtual ~Fl_Toggle_Tree();

  virtual int handle(int event);

  /**
   * Returns the current node (as set with the traversal functions).
   */
  Fl_Toggle_Node* current(void) {
    return (Fl_Toggle_Node *)t_current_;
  }

  /**
   * Returns the state of the Fl_Toggle_Tree widget. Enumerated states 
   * include: FL_TOGGLE_NONE = 0, FL_TOGGLE_SELECT = 1,
   * FL_TOGGLE_RESELECT = 2, FL_TOGGLE_SELECT_MASK = 3, 
   * FL_TOGGLE_OPENED = 4, FL_TOGGLE_CLOSED = 8 and
   * FL_TOGGLE_HIT = 16.
   */
  Fl_ToggleState state(void) {
    return state_;
  }

  /**
   * Set the selection text color for lines in the browser.
   */
  void selection_label_color(Fl_Color c) {
    selection_label_color_ = c;
  }

  /**
   * Get the selection text color for lines in the browser.
   */
  Fl_Color selection_label_color(void) {
    return selection_label_color_;
  }

  /**
   * Sets the alternating background color for lines in the browser.
   */
  void alternate_color(Fl_Color c) {
    alternate_color_ = c;
  }

  /**
   * Gets the alternating background color for lines in the browser.
   */
  Fl_Color alternate_color(void) {
    return alternate_color_;
  }

  /**
   * Sets the trim color that seperates lines of text in the browser. 
   */
  void trim_color(Fl_Color c) {
    trim_color_ = c;
  }

  /**
   * Gets the trim color that seperates lines of text in the browser. 
   */
  Fl_Color trim_color(void) {
    return trim_color_;
  }

  /**
   * Sets if toggled items are indented or not. 
   */
  void indent_toggles(int b) {
    indent_toggles_ = b;
  };

  /**
   * Gets if toggled items are indented or not. 
   */
  int indent_toggles(void) {
    return indent_toggles_;
  };

  /**
   * Sets if lines are drawn between toggle nodes.
   */
  void draw_lines(int b) {
    draw_lines_ = b;
  };

  /**
   * Gets if lines are drawn between toggle nodes.
   */
  int draw_lines(void) {
    return draw_lines_;
  };

  /**
   * Open node n. This reveals any sub items belonging to n. 
   */
  void open(Fl_Toggle_Node* node);

  /**
   * Close node n. This hides any sub items belonging to n. 
   */
  void close(Fl_Toggle_Node* node);

  /**
   * Set the horizontal label offset to x pixels. 
   */
  void label_offset(int l) {
    label_offset_ = l;
  }

  /**
   * Set the horizontal pixmap offset to x pixels. 
   */
  void pixmap_offset(int l) {
    pixmap_offset_ = l;
  }

  /**
   * Set the pixmap displayed when a node is "open".
   */
  void opened_pixmap(Fl_Pixmap *);

  /**
   * Set the pixmap displayed when a node is "closed".
   */
  void closed_pixmap(Fl_Pixmap *a);

  /**
   * Get the pixmap displayed when a node is "open".
   */
  Fl_Pixmap * opened_pixmap() {
    return opened_pixmap_;
  }

  /**
   * Get the pixmap displayed when a node is "closed".
   */
  Fl_Pixmap * closed_pixmap() {
    return closed_pixmap_;
  }

  /**
   * Gets the current column width array. This array is zero-terminated 
   * and specifies the widths in pixels of each column. The
   * text is split at each column_char() and each part is formatted into 
   * it's own column. After the last column any remaining text is formatted
   * into the space between the last column and the right edge of the 
   * Fl_Toggle_Tree wdiget, even if the text contains instances of
   * column_char() . The default value is a one-element array of just a 
   * zero, which makes there are no columns. 
   */
  const int* column_widths() const {return column_widths_; }

  /**
   * Sets the current array to w. Make sure the last entry is zero. 
   */
  void column_widths(const int* l) {
    column_widths_ = l;
  }

  /**
   * Gets the default text font for the lines in the browser. 
   */
  Fl_Font textfont() const {return (Fl_Font)textfont_; }

  /**
   * Sets the default text font for the lines in the browser. 
   */
  void textfont(Fl_Font s) {
    textfont_ = s;
  }

  /**
   * Gets the default text size for the lines in the browser. 
   */
  unsigned textsize() const {return textsize_; }

  /**
   * Sets the default text size for the lines in the browser. 
   */
  void textsize(unsigned s) {
    textsize_ = s;
  }

  /**
   * Gets the default text color for the lines in the browser. 
   */
  Fl_Color textcolor() const {return (Fl_Color)textcolor_; }

  /**
   * Sets the default text color for the lines in the browser. 
   */
  void textcolor(Fl_Color n) {
    textcolor_ = n;
  }

  /**
   * Gets the current column separator character. By default this is '\t' (tab).
   */
  char column_char() const {return column_char_; }

  /**
   * Sets the column separator to c. This will only have an effect if 
   * you also set column_widths().
   */
  void column_char(char c) {
    column_char_ = c;
  }

  /**
   * Traverses forward and returns the next selected node. 
   */
  Fl_Toggle_Node* selection(void);

  /**
   * Returns the i-th selected node. 
   */
  Fl_Toggle_Node* selection(int i);

  /**
   * Returns the currently selected index.
   */
  int selection_count(void);

  /**
   * Return the selected node. If multiple nodes are selected, then 
   * selected() returns 0, and selection() should be checked. Note
   * that the current() node is not necessarily equal to the selected() 
   * node. Fl_Toggle_Tree attempts to maintain the selected item
   * even while the tree is being modified. Of course, if the node 
   * is unselected or deleted by some operation, selected() will return 0. 
   */
  Fl_Toggle_Node* selected(void) {
    return (Fl_Toggle_Node *)current_;
  }

  /**
   * Sets nodes between start and end as selected. add.
   */
  void select_range(Fl_Toggle_Node* start, Fl_Toggle_Node* end, int add = 0);

  /**
   * Unselects all selected items.
   */
  void unselect(void) {
    select_range(0, 0, 0);
  }

  /* Remove an item from the tree but also select the previous line
     if possible. */

  /**
   * Removes n (and all of it's sub nodes) from the tree. If successful 
   * remove returns 1, otherwise it returns 0. 
   */
  int remove (Fl_Toggle_Node * a) {
    Fl_Toggle_Node * sel = 0;
    if (a->selected_) {
      if (a->up_)
	sel = (Fl_Toggle_Node *)a->up_;
      else if (a->prev_)
	sel = (Fl_Toggle_Node *)a->prev_;
    }
    Fl_Toggle_Tree_Base::remove((Fl_Toggle_Node_Base *) a);

    if (!sel) sel = (Fl_Toggle_Node *)first_;
    if (sel) sel->selected_ = 1;
    current_ = sel;
    redraw();
    return 1;
  }

  /**
   * Performs a find() with d as it's argument and remove()s the
   * returned node if it exists.
   */
  int remove (void * a);

  /**
   * Performs a find() with the string c as it's argument and remove()s 
   * the returned node if it exists. 
   */
  int remove (char * a);

  /**
   * Sets the current pointer to t. 
   */
  void traverse_start(Fl_Toggle_Node_Base * a) {
    Fl_Toggle_Tree_Base::traverse_start(a);
  }

  /**
   * Sets the traversal pointer to 
   * first() and then returns first(). The second form is provided for 
   * convenience. 
   */
  Fl_Toggle_Node * traverse_start() {
    return (Fl_Toggle_Node *) Fl_Toggle_Tree_Base::traverse_start();
  }

  /**
   * This method traverses forward through the tree. Traversal through 
   * the node tree is done by a depth first traversal that updates the 
   * current node pointer. If traverse_forward returns 0, then the 
   * current node pointer has reached the end of the tree. Otherwise, 
   * traverse_forward returns the next node in the tree. 
   * 
   * The visible flag should be set to 1 if you want to restrict traversal 
   * to the visible tree (the Fl_Toggle_Node_Bases that are not closed). 
   * The depth variable is updated with the new node depth, if the old 
   * node depth is passed to traverse_forward. 
   */
  Fl_Toggle_Node * traverse_forward(int visible, int &depth) {
    return (Fl_Toggle_Node *) Fl_Toggle_Tree_Base::traverse_forward(visible, depth);
  }

  /**
   * Same as traverse_forward(0, temp). 
   */
  Fl_Toggle_Node * traverse_forward() {
    return (Fl_Toggle_Node *) Fl_Toggle_Tree_Base::traverse_forward();
  }

  Fl_Toggle_Node * traverse_backward() {
    return (Fl_Toggle_Node *) Fl_Toggle_Tree_Base::traverse_backward();
  }

  /**
   * Finds the first node in the tree that matches the string c. 
   * If no node matches c, then find returns 0.
   */
  Fl_Toggle_Node * find (void * a);

  /**
   * Finds the first node in the tree whose data pointer is equal to 
   * the pointer d. If no node matches d, then find returns 0. 
   */
  Fl_Toggle_Node * find (char * a);

  /**
   * Inserts n as the next sub item after the current node. If the tree 
   * is empty, then n becomes the first node of the toggle tree.
   */
  Fl_Toggle_Node * add_sub(char* label = 0, int can_open = 1,
                          Fl_Pixmap* pixmap = 0, void * d = 0) {
    Fl_Toggle_Node * node;
    Fl_Toggle_Tree_Base::add_sub(node = new Fl_Toggle_Node(label, can_open, pixmap, d));
    return node;
  }

  /**
   * Inserts n as the next item after the current node. If the tree 
   * is empty, then n becomes the first node of the toggle tree. 
   */
  Fl_Toggle_Node * add_next(char* label = 0, int can_open = 1,
                           Fl_Pixmap* pixmap = 0, void * d = 0) {
    Fl_Toggle_Node * node;
    Fl_Toggle_Tree_Base::add_next(node = new Fl_Toggle_Node(label, can_open, pixmap, d));
    return node;
  }

  /**
   * Equivalent to add_sub(new Fl_Toggle_Node(label, can_open, pixmap, d)). 
   */
  void add_sub(Fl_Toggle_Node * a) {
    Fl_Toggle_Tree_Base::add_sub(a);
  }

  /**
   * Equivalent to add_next(new Fl_Toggle_Node(label, can_open, pixmap, d)). 
   */
  void add_next(Fl_Toggle_Node * a) {
    Fl_Toggle_Tree_Base::add_next(a);
  }

  /**
   * Sort the tree by label.
   */
  static int sort_by_label(Fl_Toggle_Node_Base* a, Fl_Toggle_Node_Base* b);

  /**
   * If on, this causes editing to occur if an item is reselected.
   */
  void edit_on_reselect(int b) {
    edit_on_reselect_ = b;
  }

  /**
   * Set the callback to invoke when editing.
   */
  void edit_callback(Fl_Callback* c, void* p);

  /**
   * Set the callback to invoke when editing.
   */
  void edit_callback(Fl_Callback* c);

  /**
   * Set the callback to invoke when editing.
   */
  void edit_callback(Fl_Callback0*c);

  /**
   * Set the callback to invoke when editing.
   */
  void edit_callback(Fl_Callback1*c, long p = 0);

  /**
   * The default edit callback.
   */
  static void edit_default_callback(Fl_Input* input, void* ptr);

  /**
   * Stop editing an entry.
   */
  void end_edit(void);

protected:
  virtual void edit(Fl_Toggle_Node* t, int cx, int cy);

  void draw_label(char* str, int indent, int x, int y, int w, int h);
  virtual void draw_node(int depth, int cy, Fl_Toggle_Node_Base* node);
  int label_offset_;
  int pixmap_offset_;
  int indent_toggles_;
  int edit_on_reselect_;
  int draw_lines_;
  Fl_Color alternate_color_;
  Fl_Color selection_label_color_;
  Fl_Color trim_color_;
  const int* column_widths_;
  char column_char_;

  Fl_Font textfont_;
  unsigned textsize_;
  Fl_Color textcolor_;

  Fl_ToggleState state_;
  Fl_Pixmap* opened_pixmap_;
  Fl_Pixmap* closed_pixmap_;
  static Fl_Pixmap* s_opened_pixmap_;
  static Fl_Pixmap* s_closed_pixmap_;

  int selection_i_;
  int selection_count_;
  Fl_Toggle_Node* selection_current_;

  Fl_Input *edit_input_;
};

/**
 * A file (peice of paper) xpm image.
 */
extern char * tt_file_small_xpm[];

/**
 * A file folder xpm image.
 */
extern char * tt_folder_small_xpm[];

/**
 * An open toggle xpm image.
 */
extern char * tt_open_icon_xpm[];

/**
 * A closed toggle xpm image.
 */
extern char * tt_closed_icon_xpm[];

#endif

--- NEW FILE: FDate.H ---
/* -*-C++-*- 

   "$Id: FDate.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef __FDATE_H__
#define __FDATE_H__

#include <Flek/FBase.H>
// CET - libstdc++ ios evil on Linux
//#include <iostream.h>

typedef enum {
  SUNDAY,
  MONDAY,
  TUESDAY,
  WEDNESDAY,
  THURSDAY,
  FRIDAY,
  SATURDAY
} FWeekday;

typedef enum {
  JANUARY = 1,
  FEBRUARY,
  MARCH,
  APRIL,
  MAY,
  JUNE,
  JULY,
  AUGUST,
  SEPTEMBER,
  OCTOBER,
  NOVEMBER,
  DECEMBER
} FMonth;

/** @package libflek_core
 * FDate provides a date class that stores the day, month and year.
 */
class FDate : public FBase
{

 public:

  /**
   * Default constructor.
   */
  FDate ();

  /**
   * Three argument constructor.  Initializes this object with the
   * year, month and day.
   * 
   * @param y The year.
   * @param m The month.
   * @param d The day.
   */
  FDate (int y, int m, int d);

  /**
   * Copy constructor.
   * 
   * @param src The FDate object to copy initial values from.
   */
  FDate (const FDate& src);

  /* (ScanDoc doesn't like this one)
   * Copy method.  This virtual method makes a new copy of this object.
   * 
   * @return The pointer (FBase::Ptr) to the new FDate instance.
   */
  virtual FBase::Ptr copy () const;

  /**
   * Sets the date from the year, month, and day.
   * 
   * @param y The year.
   * @param m The month, 1 through 12.
   * @param d The day, 1 through the numbers of days in that month.
   */
  void set_date (int y, int m, int d);

  /**
   * Sets the date value from another FDate object.
   * 
   * @param src The FDate object to set values from.
   */
  void set_date (const FDate& src);

  /**
   * Sets the date format.
   * 
   * @param fmt The date format.
   */
  void set_format (int fmt);

  /**
   * Set the date value to today's date.
   */
  void today ();

  /**
   * Sets the year.
   * 
   * @param y The year to associate with this object.
   */
  void year (int);

  /** 
   * Gets the year.
   * 
   * @return The year associated with this object.
   */
  int year ();

  /**
   * Sets the month.
   * 
   * @param m The month to associate with this object.
   */
  void month (int m);

  /**
   * Gets the month.
   * 
   * @return The month associated with this object.
   */
  int  month ();

  /**
   * Sets the day.
   * 
   * @param d The day of the month to associate with this object.
   */
  void day (int d);

  /**
   * Gets the day.
   * 
   * @return The day of the month associated with this object.
   */
  int day ();

  /**
   * Gets the Julian date.
   * 
   * @return The julian date value for this object.
   */
  double julian_date ();

  /**
   * Equality comparison of two dates.
   * 
   * @param src The FDate object to compare this one to.
   * @return True if this object and src are equal.  False otherwise.
   */
  bool operator== (const FDate& src);

  /**
   * Inequality comparison of two dates.
   *
   * @param src The FDate object to compare this one to.
   * @return True if this object and src are <b>not</b> equal.  False otherwise.
   */
  bool operator!= (const FDate& src);

  /**
   * Comparison of two dates.
   * 
   * @param src The FDate object to compare this one to.
   * @return True if this FDate object is less than the src object.  False otherwise.
   */
  bool operator< (const FDate& src);

  /**
   * Comparison of two dates.
   *
   * @param src The FDate object to compare this one to.
   * @return True if this FDate object is greater than the src object.  False otherwise.
   */
  bool operator> (const FDate& src);

  /**
   * Sets one date equal to another date.
   *
   * @param src The FDate object to set values from.
   */
  void operator= (const FDate& src);

  /**
   * Adds days to the date.
   * 
   * @param d The number of days to add to this date.
   */
  const FDate &operator+= (int d);

  /**
   * Pre-increment operator.  Increment the date by one day.
   */
  FDate &operator++ ();

  /**
   * Post-increment operator. Increment the date by one day.
   */
  FDate operator++ (int);

  /**
   * ostream operator.
   */
  // CET - libstdc++ ios evil on Linux
  // friend ostream& operator << (ostream &, const FDate &);

  /**
   * Gets wether day d is at the end of the month.
   * 
   * @param d The day to check.
   * @return True if d is at the end of the month.  False otherwise.
   */
  bool end_of_month (int d);

  /**
   * Gets wether year y is a leap year.
   * 
   * @param y The year to check.
   * @return True if the year is a leap year.  False otherwise.
   */
  static bool leap_year (int y);

  /**
   * Gets wether the year associated with this object is a leap year.
   * 
   * @return True if the year is a leap year.  False otherwise.
   */
  bool leap_year ()
    { return leap_year (Year); }

  /**
   * Gets wether the passed date is valid.
   * 
   * @param y The year.
   * @param m The month, 1 through 12.
   * @param d The day, 1 through the numbers of days in that month.
   * @return True if the year, month and day make a valid date.  False otherwise.
   */
  static bool valid (int y, int m, int d);

  /**
   * Gets wether the current date is valid.
   * 
   * @return True if the year, month and day make a valid date.  False otherwise.
   */
  bool valid ()
    { return valid (Year, Month, Day); }

  /**
   * Gets the number of days in the month for a given month and leap value.
   * 
   * @param m The month, 1 through 12.
   * @param leap Should be 1 if the associated year is a leap year, 0 otherwise.
   * @return The number of days in the month.
   */
  static int days_in_month (int m, int leap);
  
  /**
   * Gets the number of days in the month for this date.
   *
   * @return The number of days in the month.
   */
  int days_in_month () 
    { return days_in_month (Month, leap_year (Year)); }
  
  /**
   * Gets the day of the year for the passed date.
   * 
   * @param y The year.
   * @param m The month, 1 through 12.
   * @param d The day, 1 through the numbers of days in that month.
   * @return The day of the year.
   */
  static int day_of_year (int y, int m, int d);
  
  /**
   * Gets the day of the year for this date.
   * 
   * @return The day of the year.
   */
  int day_of_year () 
    { return day_of_year (Year, Month, Day); }

  /**
   * Gets the day of the epoch for the passed date.
   * 
   * @param y The year.
   * @param m The month, 1 through 12.
   * @param d The day, 1 through the numbers of days in that month.
   * @return The day of the epoch.
   */
  static int day_of_epoch (int y, int m, int d);
  
  /**
   * Gets the day of the epoch for this date.
   * 
   * @return The day of the epoch.
   */
  int day_of_epoch () 
    { return day_of_epoch (Year, Month, Day); }

  /**
   * Gets the day of the week for the passed date.
   * 
   * @param y The year.
   * @param m The month, 1 through 12.
   * @param d The day, 1 through the numbers of days in that month.
   * @return The day of the week, 1 through 7.
   */
  static int day_of_week (int y, int m, int d);

  /**
   * Gets the day of the week for this date.
   * 
   * @return The day of the week, 1 through 7.
   */
  int day_of_week () 
    { return day_of_week (Year, Month, Day); }
  
  /**
   * Decrement the date by one month.
   */
  void previous_month ();

  /**
   * Increment the date by one month.
   */
  void next_month ();

  /**
   * Decrement the date by one year.
   */
  void previous_year ();
  
  /**
   * Increment the date by one year.
   */
  void next_year ();

  /**
   * Convert the date to a string.
   * 
   * @param fmt The format to use during conversion.
   */
  char* to_string (int fmt) const;
  
  /**
   * Convert the date to a string using the current format.
   */
  char* to_string () const;

  /**
   * An array of days of the month for a non leap year, 1-12. (0 is ignored.)
   */
  static const int days[];
  
  /**
   * An array of total days since the beginning of the year for
   * each month, 1-12.  (0 is ignored.)
   */
  static const int julian_days[2][13];

  /**
   * An array of month names.
   */
  static const char* month_name[];
  
private:

  int  Year;
  int  Month;
  int  Day;
  int  Fmt;
  void help_increment ();

};

#endif

--- NEW FILE: Fl_Calendar.H ---
/* -*-C++-*- 

   "$Id: Fl_Calendar.H,v 1.1 2006-10-03 11:24:49 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FL_CALENDAR_H_
#define _FL_CALENDAR_H_

#include <FL/Fl_Group.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Repeat_Button.H>
#include <FL/Fl_Input.H>

#ifdef PIXIL
#include "nxbutton.h"
#include "nxbox.h"
#endif

#include <Flek/FDate.H>

#define	DOE_MIN		1		/* January 1, 1 */
#define	DOE_MAX		3652059		/* December 31, 9999 */
#define	YEAR_MIN	1
#define	YEAR_MAX	9999

enum Cal_Type {
        DAY = 0,
        WEEK = 1,
        MONTH = 2
};

/** @package libflek_ui
 * Fl_Calendar_Base is a widget that allows a user to select a date
 * (day, month, and year) with a wall style calendar. 
 */

#ifdef PIXIL
class Fl_Calendar_Base : public Fl_Group {
#else
class Fl_Calendar_Base : public Fl_Group, public FDate {
#endif

public:
  /**
   * The constructor for an empty Fl_Calendar_Base.
   */
#ifdef PIXIL
  Fl_Calendar_Base (int x, int y, int w = (7*20), int h = (6*20),   
		    const char *l = 0, Cal_Type type = DAY);
#else
  Fl_Calendar_Base (int x, int y, int w = (7*20), int h = (6*20),   
		    const char *l = 0);
#endif

  void update ();

  /**
   * Resize the buttons contained in Fl_Calendar_Base to
   * fit in the passed dimensions.
   *
   * @param cx The calendar x position.
   * @param cy The calendar y position.
   * @param cw The calendar width.
   * @param ch The calendar height.
   */
  void csize (int cx, int cy, int cw, int ch);

  /**
   * Returns a pointer to the button for the day D in the Fl_Calendar. 
   */
  Fl_Button * day_button (int i);
   
#ifdef PIXIL
  int year() {return date.year();}
  void year(int y) {date.year(y);}
  int month() {return date.month();}
  void month(int m) {date.month(m);}
  int day() {return date.day();}
  void day(int d) {date.day(d);}
  void set_date(int y, int m, int d) {date.set_date(y, m, d);}
  int days_in_month() {return date.days_in_month();}
  void previous_month() {date.previous_month();}
  void previous_year() {date.previous_year();}
  void next_year() {date.next_year();}
  char *to_string(int fmt) const {return date.to_string(fmt);}
  char *to_string() const {return date.to_string();}
  static const char* month_name[];
  
  int type() {return _type;}
#endif

 protected:
  
  int cal_x;
  int cal_y;
  int cal_w;
  int cal_h;

#ifdef PIXIL
  int m_nRows;
  FDate date;
  int _type;
#endif

  Fl_Button * days[6*7];
};

/**
 * Fl_Calendar is a subclass of Fl_Calendar.  This widget adds 
 * day labels and controllers to the base calendar class.
 * <p><img src="Fl_Calendar.png">
 */
class Fl_Calendar : public Fl_Calendar_Base 
{

 public:
  
  /**
   * The constructor for an empty Fl_Calendar.
   */
#ifdef PIXIL

  Fl_Calendar (int x, int y, int w = (7*20), int h = (8*20), 
  		    const char *l = 0, bool bCaption = true, Cal_Type type = DAY);
#else
  Fl_Calendar (int x, int y, int w = (7*20), int h = (8*20), 
  		    const char *l = 0);
#endif

  /**
   * Sets the value of the widget back by one month. 
   */
  void previous_month ();

  /**
   * Sets the value of the widget forward by one month. 
   */
  void next_month ();

  /**
   * Sets the value of the widget back by one year. 
   */
  void previous_year ();

  /**
   * Sets the value of the widget forward by one year. 
   */
  void next_year ();

#ifdef PIXIL
  void update_buttons(void);
#endif

  /**
   * Updates the widget after values have been changed.
   */  
  void update ();

  /**
   * Resize the buttons contained in Fl_Calendar_Base to
   * fit in the passed dimensions.
   *
   * @param cx The calendar x position.
   * @param cy The calendar y position.
   * @param cw The calendar width.
   * @param ch The calendar height.
   */
  void csize (int cx, int cy, int cw, int ch);
  int  handle (int);

  /**
   * Sets the Calendar's selection color.
   *
   * @param color The calendar's selection color.
   */  
  void selection_color(Fl_Color c) {
	Fl_Widget::selection_color(c);
	for(int i = 0; i < 6*7; i++) {
		if(days[i]->color() == days[i]->selection_color()) {
			days[i]->color(c);
		}
		days[i]->selection_color(c);
	}
  }

  /**
   * Gets the Calendar's selection color.
   *
   * @return The calendar's selection color.
   */  
  Fl_Color selection_color() const {
    return Fl_Group::selection_color();
  }

  /**
   * Gets the user selected day.  This method differs
   * from the day() method in that if a user has not
   * selected a day the return value is zero.
   *
   * @return The selected day if the user has selected a day, 0 otherwise.
   */
  int selected_day() {return selected_day_;}

  /**
   * Sets the user selected day.  If d is non zero, this
   * method also sets the day.
   *
   * @return The selected day if the user has selected a day, 0 otherwise.
   */
  int selected_day(int d) {selected_day_ = d; if (d) day(d); return selected_day_; }

 protected:
  
  Fl_Box * weekdays[7];
#ifdef PIXIL
  NxBox * caption;
  NxButton * nxt_month;
  NxButton * prv_month;
  NxButton * nxt_year;
  NxButton * prv_year;

  bool m_bCaption;
#else
  Fl_Box * caption;
  Fl_Repeat_Button * nxt_month;
  Fl_Repeat_Button * prv_month;
  Fl_Repeat_Button * nxt_year;
  Fl_Repeat_Button * prv_year;
#endif

  int selected_day_;
};


// Is Fl_Agenda_Calendar really necessary?  I don't see how title_height
// makes the widget look any better.  - James

/**
 * Fl_Agenda_Calendar is a subclass of Fl_Calendar.  This widget has a
 * slightly different user interface used for Agenda PDA.
 */
class Fl_Agenda_Calendar : public Fl_Calendar
{

 public:
  
  /**
   * The constructor for an empty Fl_Agenda_Calendar.
   */
  Fl_Agenda_Calendar (int x, int y, int w = (7*20), int h = (8*20), 
		      const char *l = 0, int title_height = -1);
};

/**
 * An input for getting and setting a date.
 */
class Fl_Date_Input : public Fl_Group  {

 protected:
  
  Fl_Input   Input;
  Fl_Button  Btn;
  
  int xpos;
  int ypos;
  int width;
  int height;
  int popcalfmt;
  
 public:

  /**
   * Default constructor.
   * 
   * @param x The x coordinate.
   * @param y The y coordinate.
   * @param w The width of this widget.
   * @param h The height of this widget.
   * @param l The label.
   */
  Fl_Date_Input (int x, int y, int w, int h, char * = 0);
  
  void format (int);
  
  /**
   * Gets the date value.
   * 
   * @return The date string.
   */
  const char *value ();

  /**
   * Sets the date value.
   * 
   * @param date The date string.
   */
  void value (const char* date);

#ifndef FLEK_FLTK_2
  void text_font (int);
  void textfont (int t) { text_font(t); }
  void textsize (int t) { text_size(t); }
#else
  void text_font (Fl_Font);
#endif
  void text_size (int);
  
  void btnDate_Input_cb_i ();
  
};


#endif

--- NEW FILE: FSGI.H ---
/* -*-C++-*- 

   "$Id: FSGI.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef __FSGI__
#define __FSGI__

#include <Flek/FImage.H>

/** @package libflek_core
 * The fSGI class provides static methods that read, write and test SGI images,
 * which are also refered to as "RGB" or "Iris" images.
 */
class FSGI {
 public:

  enum {
    NONE = 0,
    RLE = 1,
    ARLE = 2,
    MAGIC = 474
  };

  /**
   * Check to see if this seems to be a valid SGI format image.
   */
  static bool valid (char *filename);

  /**
   * Read an SGI Image from disk and return a new FImage object.
   */
  static FImage * read (char *filename);

  /**
   * Write an SGI Image to disk from an FImage object.
   */  
  static int write (char *filename, FImage* img, int compression = RLE, int channels=3);

};

#endif

--- NEW FILE: types.H ---
typedef unsigned int uint;
typedef unsigned short ushort;

--- NEW FILE: Flve_Input.H ---
//	======================================================================
//	File:    Flve_Input.h - Flve_Input implementation
//	Library: flvw - FLTK Widget
//	Version: 0.1.0
//	Started: 01/12/2000
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	Flve_Input implements cell text editing for a list/table.
//
// 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 FLVE_INPUT_H
#define FLVE_INPUT_H

#include <FL/Fl_Input.H>
#include <Flek/Flv_List.H>
#include <stdio.h>

class Flve_Input : public Fl_Input
{
public:
	Flve_Input( int X, int Y, int W, int H, const char *l=0 ) :
		Fl_Input(X,Y,W,H) {	owner=NULL;	};
	Fl_Widget *owner;
protected:
	int handle(int event );
};

#endif

--- NEW FILE: Flve_Combo.H ---
//	======================================================================
//	File:    Flve_Combo.h - Flve_Combo implementation
//	Library: flvw - FLTK Widget
//	Version: 0.1.0
//	Started: 01/12/2000
//
//	Copyright (C) 1999 Laurence Charlton
//
//	Description:
//	Flve_Combo implements combo box functionality
//	Included are select from list, text with list, incremental search
//
// 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 FLVE_COMBO_H
#define FLVE_COMBO_H

#include <FL/Fl_Widget.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Input.H>
#include <Flek/Flv_List.H>

#define flv_ctrl(x) ((x>='a' && x<='z'?x-('a'-'A'):x)|0x100)
#define flv_alt(x) ((x>='a' && x<='z'?x-('a'-'A'):x)|0x200)
#define flv_shift(x) ((x>='a' && x<='z'?x-('a'-'A'):x)|0x400)

class Flv_Combo_Item
{
public:
	Flv_Combo_Item();
	virtual ~Flv_Combo_Item();

	const char *item(void);
	void item(const char *v);
	long value(void);
	void value(long v);
protected:
	char *vitem;
	long vvalue;
};

class Flv_Combo_Items
{
public:
	Flv_Combo_Items();
	~Flv_Combo_Items();

	int count(void)										//	# of styles
		{	return vcount;	}

	void add( const char *item, long v=0L );
	void insert( int index, const char *item, long v=0L );
	void remove( int index );
	void change( int i, const char *item, long v );
	void change( int i, const char *item );
	void change( int i, long v );

	void sort(void);									//	Sort list
	void clear(void);									//	Clear list
	int index(void)										//	Get current index
		{	return vcurrent;	};
	void index(int i);								//	Set current index

	int findi( const char *v );				//	Find starting with v (-1 not found)
	int find( const char *v );				//	Find text return index (-1 not found)
	int find( long v );								//	Find value return index (-1 not found)

	Flv_Combo_Item *current(void);
	Flv_Combo_Item &operator[](int index);
private:
	void make_room_for( int n );
	Flv_Combo_Item **list;								//	Array of item pointers
	int vcount;														//	# of item pointers defined
	int vallocated;												//	# of item pointers allocated
	int vcurrent;													//	Current item index
	bool nodups;
};


class Flve_Combo : public Fl_Widget
{
public:
	Flve_Combo(int x, int y, int w, int h, const char *l );
	~Flve_Combo();
	virtual void resize(int x, int y, int w, int h);
	void list_title(const char *v);
	void open_list(void);
	const char *value();
	void value(const char *v);
	int display_rows()
		{	return vdisplay_rows;	};
	void display_rows(int v);
	int drop_key(void)
		{	return vdrop_key;	}
	int drop_key( int v )
		{	return vdrop_key = v;	}

	bool incremental_search(void)
		{	return vincremental_search;	}
	bool incremental_search(bool v)
		{	return (vincremental_search=v);	}
	bool list_only(void)
		{	return vlist_only;	}
	bool list_only(bool v);
	
	Flv_Combo_Items item;
	Fl_Window *list;
	
	  void end () {}
	  void textfont (int) {}
	  void textsize (int) {}
	  
protected:
	bool vincremental_search;
	bool vlist_only;
	int vdrop_key;
	char *vlist_title;
	int vdisplay_rows;
	int handle(int event);
	void draw(void);
	Fl_Input *input;
};
#endif


--- NEW FILE: FVector3.H ---
/* -*-C++-*- 

   "$Id: FVector3.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

// The original vector, matrix, and quaternion code was written by
// Vinod Srinivasan and then adapted for Flek.

#ifndef _FVECTOR3_H_
#define _FVECTOR3_H_

#include <Flek/FVector.H>

/** @package libflek_core
 * FVector3 is a 3 dimensional vector represented internally as an array of 
 * doubles.  This class is related to FVector2 and FVector4 which are 
 * 2-D and 4-D versions of this class.  All FVector classes are forward
 * declared in FVector.h.
 */

class FVector3 : public FBase
{
public:

  typedef FVector3* Ptr;
  
  /**
   * The default constructor sets each element in the vector to 0.
   */
  FVector3 () 
    : FBase ()
    {
      elem[0] = elem[1] = elem[2] = 0.0;
    }

  /**
   * This one argument constructor intializes all elements in the vector
   * with the given value.
   */
  FVector3 (double val) 
    : FBase ()
    {
      elem[0] = elem[1] = elem[2] = val;
    }
     
  /**
   * This one argument constructor initializes the vector with the first
   * three elements in the given array.
   */
  FVector3 (double * arr)
    : FBase ()
    {
      elem[0] = arr[0]; elem[1] = arr[1]; elem[2] = arr[2];
    }

  /**
   * This three argument constructor initializes the vector with the
   * passed values.
   */
  FVector3 (double val1, double val2, double val3=0.0)
    : FBase ()
    {
      elem[0] = val1; elem[1] = val2; elem[2] = val3;
    }
     
  /**
   * The copy constructor initializes this vector with the contents 
   * of another vector.
   */
  FVector3 (const FVector3& vec)
    : FBase (vec)
    {
      elem[0] = vec.elem[0]; elem[1] = vec.elem[1]; elem[2] = vec.elem[2];
    }

  /**
   * This constructor initializes the vector from the contents of a
   * FVector2 (a 2D vector).  The third element is set to zero.
   */
  FVector3 (const FVector2& vec)
    : FBase ()
    {
      copy_from (vec);
    }
     
  /**
   * This constructor initializes the vector from the contents of a
   * FVector4.  The third element in the FVector4 is ignored.
   */
  FVector3 (const FVector4& vec)
    : FBase ()
    {
      copy_from (vec);
    }
     
  /**
   * The virtual destructor does nothing.
   */
  virtual ~FVector3 ()
    {}

  /**
   * Assignment operator from another FVector3.
   */
  FVector3& operator = (const FVector3& vec)
    {
      elem[0] = vec.elem[0]; elem[1] = vec.elem[1]; elem[2] = vec.elem[2];
      return (*this);
    }
  
  /** 
   * Assignment operator from a scalar.  All elements are set to 
   * the scalar value.
   */
  FVector3& operator = (double scalar)
    {
      elem[0] = elem[1] = elem[2] = scalar;
      return (*this);
    }

  /** 
   * Assignment operator from a FVector2.  The third element set to 0.
   */
  FVector3& operator = (const FVector2& vec)
    {
      copy_from (vec);
      return (*this);
    }
  
  /**
   * Assignment operator from a FVector4.  Copies first 3 elements.
   */
  FVector3& operator = (const FVector4& vec)
    {
      copy_from (vec);
      return (*this);
    }

  /**
   * Make a copy of the object.
   */
  virtual FBase::Ptr copy (void) const
    {
      Ptr vec = new FVector3 (*this);
      return vec;
    }

  /** 
   * Set each element vector to the given values.
   */
  void set (double v1, double v2, double v3)
    {
      elem[0] = v1; elem[1] = v2; elem[2] = v3;
    }

  /** 
   * Set each element vector to the given value.
   */
  void set (double val)
    {
      elem[0] = elem[1] = elem[2] = val;
    }
     
  /** 
   * Set elements of vector to default values.
   */
  void reset (void)
    {
      set (0.0);
    }
     
  /** 
   * Get the elements of vector into given values.
   */
  void get (double& v1, double& v2, double& v3) const
    {
      v1 = elem[0]; v2 = elem[1]; v3 = elem[2];
    }
     
  /**
   * Fill an array with the elements of the vector.
   */
  void fill_array (double arr[3]) const
    {
      arr[0] = elem[0]; arr[1] = elem[1]; arr[2] = elem[2];
    }
     
  /** 
   * Element access operator.  For efficiency, this doesn't check for 
   * valid indices
   */
  double& operator [] (uint index)
    {
      return elem[index];
    }

  /** 
   * Element access operator.  For efficiency, this doesn't check for 
   * valid indices
   */
  double operator [] (uint index) const
    {
      return elem[index];
    }

  /**
   * Arithmetic operator for additive assignment.
   */
  void operator += (const FVector3& vec)
    {
      elem[0] += vec.elem[0]; elem[1] += vec.elem[1]; elem[2] += vec.elem[2];
    }

  /**
   * Arithmetic operator for subtractive assignment.
   */
  void operator -= (const FVector3& vec)
    {
      elem[0] -= vec.elem[0]; elem[1] -= vec.elem[1]; elem[2] -= vec.elem[2];
    }

  /**
   * Arithmetic operator for multiplicative (scalar) assignment.
   */
  void operator *= (double scalar)
    {
      elem[0] *= scalar; elem[1] *= scalar; elem[2] *= scalar;
    }
  
  /**
   * Arithmetic operator for divisive (scalar) assignment.
   */
  void operator /= (double scalar)
    {
      elem[0] /= scalar; elem[1] /= scalar; elem[2] /= scalar;
    }

  /**
   * Arithmetic operator for addition.
   */ 
  FVector3 operator + (const FVector3& vec) const
    {
      FVector3 sum(*this);
      sum += vec;
      return sum;
    }

  /**
   * Arithmetic operator for subtraction.
   */ 
  FVector3 operator - (const FVector3& vec) const
    {
      FVector3 diff(*this);
      diff -= vec;
      return diff;
    }

  /**
   * Operator for scalar multiplication (dot product).
   */
  double operator * (const FVector3& vec) const
    {
      double dotprod = elem[0]*vec.elem[0] + elem[1]*vec.elem[1] + elem[2]*vec.elem[2];
      return dotprod;
    }

  /**
   * Operator for vector multiplication (cross product).
   */
  FVector3 operator % (const FVector3& vec) const
    {
      FVector3 crossp;
      
      crossp.elem[0] = elem[1]*vec.elem[2] - elem[2]*vec.elem[1];
      crossp.elem[1] = elem[2]*vec.elem[0] - elem[0]*vec.elem[2];
      crossp.elem[2] = elem[0]*vec.elem[1] - elem[1]*vec.elem[0];
      
      return crossp;
    }
  
  /**
   * Friend operator for negation.
   */
  friend FVector3 operator - (const FVector3& vec)
    {
      FVector3 negv (-vec.elem[0], -vec.elem[1], -vec.elem[2]);
      return negv;
    }

  /**
   * Friend operator for scalar pre-multiplication.
   */
  friend FVector3 operator * (double scalar, const FVector3& vec)
    {
      FVector3 prod (vec);
      
      prod *= scalar;
      return prod;
    }

  /**
   * Friend operator for scalar post-multiplication.
   */  
  friend FVector3 operator * (const FVector3& vec, double scalar)
    {
      FVector3 prod (vec);
      
      prod *= scalar;
      return prod;
    }

  /**
   * Friend operator for scalar division.
   */
  friend FVector3 operator / (const FVector3& vec, double scalar)
    {
      FVector3 prod (vec);
      
      prod /= scalar;
      return prod;
    }

  /**
   * Friend operator for element-by-element product.
   */
  friend FVector3 product(const FVector3& vec1, const FVector3& vec2)
    {
      FVector3 prod (vec1[0]*vec2[0],vec1[1]*vec2[1],vec1[2]*vec2[2]);
      
      return prod;
    }
    
  /**
   * Boolean equality operator.
   */
  bool operator == (const FVector3& vec) const
    {
      if ( (fabs(elem[0]-vec.elem[0]) > ZERO) ||
	   (fabs(elem[1]-vec.elem[1]) > ZERO) ||
	   (fabs(elem[2]-vec.elem[2]) > ZERO) )
	return false;
      return true;
    }

  /**
   * Boolean ineqality operator.
   */
  bool operator != (const FVector3& vec) const
    {
      return !( (*this) == vec );
    }

  // Other functions
  
  /**
   * Square of the norm of the vector.
   */
  friend double normsqr (const FVector3& vec)
    {
      double nsq = sqr (vec.elem[0]) + sqr (vec.elem[1]) + sqr (vec.elem[2]);
      return nsq;
    }
  
  /**
   * Norm of the vector.
   */
  friend double norm (const FVector3& vec)
    {
      return sqrt (normsqr (vec));
    }

  /** 
   * Length (norm) of the vector.
   */
  double length ()
    {
      return norm (*this);
    }
  
  /**
   * Normalize.  Returns previous norm.
   */
  friend double normalize (FVector3& vec)
    {
      double n = norm (vec);
      if (is_non_zero (n) == true) vec /= n;
      return n;
    }
  
  /** 
   * Returns normalized vector.
   */
  friend FVector3 normalized (const FVector3& vec)
    {
      FVector3 nvec (vec);
      normalize (nvec);
      return nvec;
    } 

  friend double distance (const FVector3& v1, const FVector3& v2)
    {
      FVector3 t;
      t = v1 - v2;
      return t.length ();
    }
  
  /**
   * Swap the elements of two FVector3s.
   */
  friend void swap (FVector3& vec1, FVector3& vec2)
    {
      swap (vec1.elem[0], vec2.elem[0]);
      swap (vec1.elem[1], vec2.elem[1]);
      swap (vec1.elem[2], vec2.elem[2]);
    }

  /**
   * I/O Stream extraction operator.  Of the form "[ x y z ]". 
   */ 
  friend istream& operator >> (istream& i, FVector3& vec)
    {
      remove_white_space (i);
      if ( i.peek() == '[' )
	{
	  // Correct format
	  int numread = 0; // No. of elements read
	  double val;
	  char c;
	  
	  i >> c;   // Read opening square bracket
	  while ( numread < 3 )
	    {
	      i >> val; vec.elem[numread] = val;
	      numread++;
	    }
	  
	  // Read all characters till closing bracket is found
	  // If no. of chars read is more than 10 then print an error
	  // message and exit;
	  i >> c;
	  numread = 1;
	  while ( c != ']' && numread < 10 )
	    {
	      i >> c; numread++;
	    }
	  
	  if ( numread >= 10 )
	    {
	      cerr << "operator >> FVector3 : Incorrect format. Closing ']' not"
		   << " found upto 10 characters after 3rd element of vector"
		   << endl;
	      exit(0);
	    }
	}
      
      return i;
    }

  /**
   * I/O Stream insertion operator.  Of the form "[ x y z ]". 
   */ 
  friend ostream& operator << (ostream& o, const FVector3& vec) // Insertion operator
    {
      // User can set precision from 0 to 6
      o << setiosflags (ios::fixed) << setiosflags (ios::showpoint);
      
      int oldprec = o.precision ();
      if ( oldprec < 0 ) o << setprecision(0);
      if ( oldprec > 6 ) o << setprecision(6);
      
      o << "["
	<< vec.elem[0] << " "
	<< vec.elem[1] << " "
	<< vec.elem[2]
	<< "]";
      
      o << setprecision(oldprec);
      return o;
    }

 protected:
     
     double elem[3];
  
     /**
      * Initialize the elements from a FVector2,
      */
     void copy_from (const FVector2& vec);

     /**
      * Initialize the elements from a FVector4,
      */
     void copy_from (const FVector4& vec);
};

#endif // #ifndef FVector3_H


--- NEW FILE: FPNM.H ---
/* -*-C++-*- 

   "$Id: FPNM.H,v 1.1 2006-10-03 11:24:48 dslinux_amadeus Exp $"
   
   Copyright 1999-2000 by the Flek development team.
   
   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.
   
   Please report all bugs and problems to "flek-devel at sourceforge.net".

*/

#ifndef _FPNM_H_
#define _FPNM_H_

#include <Flek/FImage.H>

/** @package libflek_core
 * The fPNM class provides static methods that read, write and test PNM images.
 * fPNM supports PBM (Portable Bitmap - ASCII (P1) and RAW (P4)), 
 * PGM (Portable Graymap - ASCII (P2) and RAW (P5)), and
 * PPM (Portable Pixmap - ASCII (P3) and RAW (P6)),  fPNM also supports the
 * oft used but very <i>non-standard</i> PPM-P7, which is basically the P6 format
 * with an alpha channel.
 */
class FPNM {
 public:

  /**
   * Check the PBM/PGM/PPM magic number to see if this image matches any of
   * the recognized formats.
   */
  static bool valid (char *filename);

  /**
   * Read a PPM from disk and return a new fImage object.
   */
  static FImage * read (char *filename);

  /**
   * Write a PPM to disk from an fImage object.
   */  
  static int write (char *filename, FImage* img);

};

#endif




More information about the dslinux-commit mailing list