// -*-C++-*- 

/*  inc/platform/Aq.hpp  */

/*
 * Author: Philogelos A. <Philogelos@yahoo.com>
 * Maintainer: Philogelos A.
 * Keywords: C++, library, containers
 *
 * Copyright (C) 1999 Philogelos A.
 *
 * This file is part of Quercus Robusta.
 *
 * Quercus Robusta 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, or (at your option)
 * any later version.
 *
 * This software 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 software; see the file COPYING.LIB.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */



#ifndef __AQ_HPP__
#define __AQ_HPP__

/* $Id$ */

#include "Top.hpp"
#include "defines.h"
#include "String.hpp"
#include "Object.hpp"
#include "platform/threads/Runnable.hpp"
#include "platform/threads/Thread.hpp"
#include "iter/enumerations/TypedEnumeration.hpp"
#include "observe/ObservableAdapter.hpp"
#include "observe/PassiveObserver.hpp"
#include "Condition.hpp"
#include "Guard.hpp"
#include "OGuard.hpp"
#include "iter/iterables/Iterable.hpp"

/**

   @author Philogelos
   @created
*/
class Aq : public virtual Top
{
public: abstract class AqEvent;
public: abstract class EventSource;
public: abstract class Window;
public: class EventDispatcher;
public: class GUISystem;
public: class AqObject;

public: class KeyEvent;
public: class ButtonEvent;
public: class MouseMotionEvent;
public: class FocusEvent;
public: class WindowEvent;
public: class DestroyEvent;
public: class ResizeEvent;
public: class SelectionEvent;

public: abstract class GraphicContext;
public: abstract class Drawable;
public: abstract class Color;
public: abstract class Painter;

public: typedef short int CoordX;
public: typedef short int CoordY;
public: typedef short int Coord;
public: typedef unsigned short int Size;
public: typedef enum { X = 0, Y = 1 } Dimension;
public: typedef class Color Colour;

public: class Point;
public: class Rect;

public: interface GUISystem : public virtual Top
{
 public: virtual Painter *createPainter( GraphicContext *aContext, 
										 Drawable *aDrawable ) const = 0;
 public: virtual boolean isCompatible( const GUISystem *anOther ) const;
};

public: abstract class AqObject : public virtual Top
{
public: AqObject( const GUISystem *aSystem );
public: virtual ~AqObject();

public: const GUISystem *getGUISystem() const;
public: virtual boolean isCompatible( const GUISystem *aSystem ) const;
public: virtual boolean isCompatible( const AqObject *anObject ) const;

protected: const GUISystem *system;
};

public: abstract class AqEvent : public virtual Condition
{
public: virtual void announce();
  
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class EventDispatcher : public virtual Object
{
public: virtual void onKeyEvent( KeyEvent *anEvent );
public: virtual void onButtonEvent( ButtonEvent *anEvent );
public: virtual void onMouseMotionEvent( MouseMotionEvent *anEvent );
public: virtual void onFocusEvent( FocusEvent *anEvent );
public: virtual void onWindowEvent( WindowEvent *anEvent );
public: virtual void onDestroyEvent( DestroyEvent *anEvent );
public: virtual void onResizeEvent( ResizeEvent *anEvent );
public: virtual void onSelectionEvent( SelectionEvent *anEvent );
  
public: virtual void onOtherEvent( AqEvent *anEvent );
  
public: virtual void onAnyEvent( AqEvent *anEvent );
};

public: abstract class EventSource : public ObservableAdapter,
		public Runnable,
		public TypedEnumeration< AqEvent >,
		public Iterable
{
public: virtual boolean  init();
public: virtual void  done();
public: virtual void  processEvent( AqEvent *anEvent );
public: virtual void *run();
public: virtual AqEvent *getNextTypedElement() = 0;
public: virtual boolean hasMoreElements();

public: boolean isDoneWithEvents() const;

public: virtual void initIterations();
public: virtual void fireOn( Top *anElement );
public: virtual boolean isMore();
public: virtual void doneIterations();

protected: boolean doneWithEvents;
};


public: class KeyEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class ButtonEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class MouseMotionEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class FocusEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class WindowEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class DestroyEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class ResizeEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class SelectionEvent : public virtual AqEvent
{
public: void dispatch( EventDispatcher *aDispatcher );
public: virtual String getClassName() const;
};

public: class Point : public virtual Object
{
public: Point( CoordX aX, CoordY aY );
public: Point( Coord *aCoord );
public: Point( const Point &aPoint );

public: virtual ~Point();

public: CoordX getX() const;
public: CoordY getY() const;

public: Coord get( Dimension aDim ) const;

public: void setX( CoordX aX );
public: void setY( CoordY aY );

public: void set( Dimension aDim, Coord aCoord );

protected: void init( CoordX aX, CoordY aY );
protected: Coord coord[ 2 ];
};

public: class Rect : public virtual Object
{
public: Rect( CoordX aX, CoordY aY, Size aWidth, Size aHeight );
public: Rect( CoordX aLUX, CoordY aLUY, CoordX aRDX, CoordY aRDY );
public: Rect( Point aLU, Size aWidth, Size aHeight );
public: Rect( Point aLU, Point aRD );

public: virtual ~Rect();

public: double getDiagonal() const;
public: Index getArea() const;

public: Point *getLU() const;
public: Point *getRD() const;

public: Size getWidth() const;
public: Size getHeight() const;

protected: void init( CoordX aLUX, CoordY aLUY, CoordX aRDX, CoordY aRDY );
protected: Point *lu;
protected: Point *rd;
};

public: abstract class GraphicContext : public AqObject
{
public: GraphicContext( GUISystem *aSystem );
};

public: abstract class Drawable : public AqObject
{
public: Drawable( GUISystem *aSystem );
};

public: abstract class Window : public Drawable
{
public: Window( GUISystem *aSystem );
public: virtual EventSource *getEventSource() const = 0;
};

public: abstract class Color : public AqObject
{
public: Color( GUISystem *aSystem );
};

public: abstract class Painter : public AqObject
{
public: Painter( GraphicContext *aContext, Drawable *aDrawable );
public: virtual ~Painter();

public: virtual void init() = 0;
public: virtual void done() = 0;

public: virtual GraphicContext *getContext() const;
public: virtual Drawable *getDrawable() const;

public: virtual void setContext( GraphicContext *aContext );
public: virtual void setDrawable( Drawable *aDrawable );

public: virtual void drawLine( CoordX aStartX, CoordY aStartY, 
							   CoordX anEndX, CoordY anEndY ) const = 0;
public: virtual void drawPLine( Point *aStart, Point *anEnd ) const;

public: virtual void drawPoint( CoordX aX, CoordY aY ) const = 0;
public: virtual void drawPPoint( Point *aPoint ) const;

public: virtual void drawString( CoordX aX, CoordY aY, String aString ) const;
public: virtual void drawCString( CoordX aX, CoordY aY, 
								  char *aString ) const = 0;

public: virtual void fillPRectangle( Rect *aRect ) const;
public: virtual void fillRectangle( CoordX aX, CoordY aY,
									Size aWidth, Size aHeight ) const = 0;

public: virtual void clearPRectangle( Rect *aRect ) const;
public: virtual void clearRectangle( CoordX aX, CoordY aY,
									 Size aWidth, Size aHeight ) const = 0;

public: virtual void copyRPFrom( Rect *aSource, Drawable *aDrawable,
								 Point *aPoint ) const;
public: virtual void copyFrom( CoordX aSourceX, CoordY aSourceY, 
							   Size aWidth, Size aHeight,
							   Drawable *aDrawable,
							   CoordX aDestX, CoordY aDestY ) const = 0;

protected: GraphicContext *context;
protected: Drawable *drawable;
};

public: class PainterGuard : public OGuard
{
public: PainterGuard( const Painter *aPainter, const Top *anOwner );
public: virtual ~PainterGuard();

public: Painter *getPainter() const;
};

};

/* $Log$ */

/* __AQ_HPP__ */
#endif

