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

/***********************************************************
Copyright 1991 by the Massachusetts Institute of Technology

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of M.I.T. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission.  M.I.T. makes no representations about the
suitability of this software for any purpose.  It is provided "as is"
without express or implied warranty.


Author: Roman J. Budzianowski - Project Athena MIT

******************************************************************/

#include <xt++/Intrinsic.h>
#include <xt++/Xaw/Layout.h>
#include <X11/StringDefs.h>
#include <iostream.h>

#ifndef LayoutSpace_h
#define LayoutSpace_h

class LayoutSpace;

class ObjectViewBase {
friend class LayoutSpace;
 private:
   String name;
 public:
   virtual void Move(XPoint&) = 0;
   virtual void Resize(XPoint&, Dimension, Dimension) = 0;
   virtual void Place(XPoint&) = 0;
   virtual void GetSize(Dimension&,Dimension&) = 0;
   virtual void GetPosition(Position&,Position&) = 0;
   virtual void MakeEditable(LayoutSpace*) = 0;

   ObjectViewBase(String n) : name(n) {}
   ~ObjectViewBase() {}
};

class WidgetObject : public ObjectViewBase {
 private:
   Widget         widget;
 public:
   virtual void Move(XPoint&);
   virtual void Resize(XPoint&, Dimension, Dimension);
   virtual void Place(XPoint&);
   virtual void GetSize(Dimension&,Dimension&);
   virtual void GetPosition(Position&,Position&);
   virtual void MakeEditable(LayoutSpace*);

   WidgetObject(Widget w, String name) : widget(w), ObjectViewBase(name) {}
   WidgetObject() : ObjectViewBase(NULL), widget(NULL) {}
};

// unused
// may use it to wrap each widget added to LayoutSpace
//
class Container : public LayoutWidget {	// should be special purpose composite
 private:
   Widget            child;		// needed ? or access directly the field in Composite
   XtTranslations    child_translations;
 public:
   Container(Widget);

   void EditMode();
   void PlayMode();
};


class LayoutSpace : public LayoutWidget {
 public:
   enum Mode { Edit, Play};

   LayoutSpace(Widget parent, ObjectViewBase* holder=NULL);
//   LayoutSpace(Core& parent) {}

   void  AddObject(ObjectViewBase* object);
   void  CreateObject(XPoint&);

   void StartMovingObject(ObjectViewBase*, XPoint&);
   void PlaceObject(XPoint&);
   void RubberbandObject(XPoint&);

   void StartResizingObject(ObjectViewBase*);
   void RubberbandSize(XPoint&);
   void ResizeObject(XPoint&);

   void PlaceNewObject(XPoint&);
   void AbortCreatingObject();

   XPoint GetEventLocation(XEvent*);
   void GetLastEvent(XEvent*);

   void InitializeWidget() 
     { 
//	cerr << "LayoutSpace:Initilize.\n";
	XDefineCursor(XtDisplay(), XtWindow(), normal_cursor); 
     }

 private:
   static  Boolean class_inited;

   // temporary storage for dynamic operations
   XPoint      current_position;
   XPoint      original_position;
   Dimension   current_width;
   Dimension   current_height;
   Dimension   original_width;
   Dimension   original_height;
   ObjectViewBase* object_holder;
   Boolean         creating_object;
   Boolean         moving_object;
   Boolean         resizing_object;

   // X data
   EventMask  grab_mask;
   GC          flip_gc;		// draw rubberband

// resources 
   Cursor      normal_cursor;
   Cursor      placement_cursor;
   Boolean     rubberband;

// private state
   Mode mode;

// private methods
   void InitializeClass();

   Boolean CreatingObjectP() { return creating_object; }

   Boolean PointerInsideP(XPoint&);
   void DrawRubberbandOfObject();
   void EraseRubberbandOfObject() { DrawRubberbandOfObject(); }

};

#endif
