// -*- C++ -*-
/*
 *  File:        math_cursor.h
 *  Purpose:     Declaration of interaction classes for mathed
 *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
 *  Created:     January 1996
 *  Description: MathCursor control all user interaction
 *
 *  Dependencies: Xlib, XForms
 *
 *  Copyright: (c) 1996, Alejandro Aguilar Sierra
 *
 *   Version: 0.5beta, Mathed & Lyx project.
 *
 *   You are free to use and modify this code under the terms of
 *   the GNU General Public Licence version 2 or later.
 */

#ifndef __MATH_DRAW__
#define __MATH_DRAW__

#include "math_inset.h"

#define MX_WAS_SUB   1
#define MX_WAS_SUPER 2

// A graphic iterator (updates position) 
class LyxMathXIter: public LyxMathIter {
 public:
   LyxMathXIter(void): LyxMathIter(NULL) { x = y = size = 0; }
   LyxMathXIter(MathParInset*);
   ~LyxMathXIter() { };

   Bool Next();
   Bool Prev();
   void GoLast();
   void GoBegin();
   void Adjust();
   inline void GetPos(int&, int&);
   inline void GetIncPos(int&, int&);
   byte* GetString(int&);
   void SetData(MathParInset *);
   int GetX(void);
   int GetY(void);
 protected:
   // This function is not recursive, as MathPar::Metrics is
   void IMetrics(int, int&, int&, int&);
   int size;
   int x, y;
   MathParInset *p;
   
   // Limits auxiliary variables
   int sx, sw;    // Position and max width of a script
   bool limits;   // true=center, false=left align (default)
   short s_type;  // Type of previous script
   
 private:
   friend class LyxMathCursor;
};


// User Interface
class LyxMathCursor {
 public:
   LyxMathCursor(MathParInset *p); 
   ~LyxMathCursor() { };
   void Insert(byte, LyxMathTextCodes);
   void Insert(LyxMathInset*, int t=LM_TC_INSET);
   void Home();
   void End();
   bool Right(bool sel=false);
   bool Left(bool sel=false);
   bool Up();
   bool Down();
   bool Pop();  
   bool Push();    
   void Draw(long unsigned pm, int x, int y);
   void Redraw(void);
   void Delete();			      
   void DelLine();
   
   void SetPos(int, int);
   void GetPos(int& x, int& y) { cursor->GetPos(x, y); }
   short GetFCode(void) { return cursor->FCode(); }
   MathParInset *GetPar(void) { return par; }
   void SetPar(MathParInset*);
   void Interpret(const char*);
   
   void SetSize(short);
   bool Limits();
   
   // Macro mode methods
   void MacroModeOpen(void);
   void MacroModeClose(void);
   bool InMacroMode(void) { return macro_mode; }
   
   // Local selection methods
   bool Selection() { return selection; }
   void SelCopy(void);
   void SelCut(void);
   void SelDel(void);
   void SelPaste(void);
   void SelStart(void);
   void SelClear(void);
   void SelGetArea(int& x1, int& y1, int& w, int& h);
 protected:
   bool macro_mode;
   void MacroModeBack(void);
   void MacroModeInsert(char); 
   
   bool selection;
   int  selpos;
   LyxMathXIter cursel;
   LyxArrayBase *selarray; 
   
   Bool is_visible; 
   long unsigned win;
   MathParInset *par;
   LyxMathXIter *cursor;
   int xc, yc;
 private:
   char macrobf[80];
   int macroln;
   MathFuncInset* imacro;
};


//--------------------   Inline Functions  -------------------------// 


inline
void LyxMathXIter::GetPos(int&xx, int& yy)
{ 
   if (p) 
     p->GetXY(xx, yy);
   else
    { xx = 0;  yy = 0; }        
   xx += x;  //yy += y;
}

inline 
int LyxMathXIter::GetX(void) 
{ 
   int xx, yy;
   GetPos(xx, yy);
   return xx; 
}

inline 
int LyxMathXIter::GetY(void) 
{ 
   int xx, yy;
   GetPos(xx, yy);
   return yy; 
}


inline
void LyxMathXIter::GetIncPos(int& xx, int& yy) 
{ 
   xx = x;  yy = y; 
}

#endif

