// -*- C++ -*-
/*
 *  File:        math_inset.h
 *  Purpose:     Declaration of insets for mathed 
 *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
 *  Created:     January 1996
 *  Description: Math paragraph and objects for a WYSIWYG math editor.
 *
 *  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.
 */

//  Note: These math insets are internal to Mathed and are not derived
//        from lyx inset.

#ifndef __MATH_INSET__
#define __MATH_INSET__

#include <stdio.h>
#include "math_defs.h"
#include "symbol_def.h"

// Functions or LaTeX keywords for objects that I don't know how to draw
// (formerly MathLatexInset)
class MathFuncInset: public LyxMathInset  {
 public: 
   MathFuncInset(char *nm, short ot=LM_OT_FUNC, short st=LM_ST_TEXT);
   ~MathFuncInset();
   LyxMathInset *Clone(void);   
   void Draw(long unsigned int pm, int x, int baseline);
   void Write(FILE *file);
   void Metrics(void);
   inline bool GetLimits(void) const;
 protected:
   int ln;
   bool lims;
};


class MathAccentInset: public LyxMathInset {
 public: 
   MathAccentInset(byte, LyxMathTextCodes, int, short st=LM_ST_TEXT);
   ~MathAccentInset() { };
   LyxMathInset *Clone(void);   
   void Draw(long unsigned int, int, int);
   void Write(FILE *file);
   void Metrics(void);
 protected:
   byte c;
   LyxMathTextCodes fn;
   int code;
   int dh, dy;
};



class MathDotsInset: public LyxMathInset {
 public:
   MathDotsInset(char*,int,short st=LM_ST_TEXT);
   ~MathDotsInset() { };
   LyxMathInset *Clone(void);
   void Draw(long unsigned int, int, int);
   void Write(FILE *file);
   void Metrics(void);
 protected:
   int dh, code;
};   

class MathSpaceInset: public LyxMathInset  {
 public: 
   MathSpaceInset(int sp, short ot=LM_OT_SPACE, short st=LM_ST_TEXT);
   ~MathSpaceInset() { };
   LyxMathInset *Clone(void);
  void Draw(long unsigned int pm, int x, int baseline);
   void Write(FILE *file);
   inline void Metrics(void);
   inline void SetSpace(int sp);
   int GetSpace(void) { return space; }
 protected:
   int space;
};


class MathBigopInset: public LyxMathInset {
 public: 
   MathBigopInset(char*, int, short st=LM_ST_TEXT);
   ~MathBigopInset() { };
   LyxMathInset *Clone(void);   
   void Draw(long unsigned int, int, int);
   void Write(FILE *file);
   void Metrics(void);
   inline bool GetLimits(void) const;
   inline void SetLimits(bool);
 protected:
   bool lims;
   int sym;   
};

 
//------- All editable insets must be derived from MathParInset.

class MathSqrtInset: public MathParInset {
 public: 
   MathSqrtInset(short st=LM_ST_TEXT);
   ~MathSqrtInset() { };   
   LyxMathInset *Clone(void);  
   void Draw(long unsigned int pm, int x, int baseline);
   void Write(FILE *file);
   void Metrics(void);
 private:
   short hmax;
};


class MathFracInset: public MathParInset {
 public: 
   MathFracInset(short st=LM_ST_TEXT);
   ~MathFracInset();
   LyxMathInset *Clone(void);   
   void Draw(long unsigned int pm, int x, int baseline);
   void Write(FILE *file);
   void Metrics(void);
   void SetData(LyxArrayBase*);
 
   // This does the same that SetData(LyxArrayBase*) but for both
   // numerator and denominator at once.
   void SetData(LyxArrayBase*, LyxArrayBase*);

   void GetXY(int& x, int& y) const;
   void SetFocus(int,int);
   LyxArrayBase * GetData(void);
   bool Up(void);
   bool Down(void);
   void Top(void) { Up(); }
   void Bottom(void) { Down(); }
   void  SetStyle(short);
 protected:
   bool upper;                 //  Par selected
   MathParInset *den;
   int w0, w1, des0, dh;
};


class MathDelimInset: public MathParInset {
 public: 
   MathDelimInset(int, int, short st=LM_ST_TEXT);
   ~MathDelimInset() { };
   LyxMathInset *Clone(void);   
   void Draw(long unsigned int, int, int);
   void Write(FILE *file);
   void Metrics(void);
 protected:
   int left, right;
   int dw, dh;
};


class MathDecorationInset: public MathParInset {
 public: 
   MathDecorationInset(int, short st=LM_ST_TEXT);
   ~MathDecorationInset() { };
   LyxMathInset *Clone(void);   
   void Draw(long unsigned int, int, int);
   void Write(FILE *file);
   void Metrics(void);
   inline bool GetLimits(void) const;
 protected:
   int deco;
   bool upper;
   int dw, dh, dy;
};


// --------------------  Inline functions ---------------------

 
inline
MathFuncInset::~MathFuncInset()
{
   if (name && GetType()==LM_OT_UNDEF) delete[] name;
}

inline
bool MathFuncInset::GetLimits() const 
{  
   return (bool)(lims && (GetStyle()==LM_ST_DISPLAY)); 
} 

inline
void MathFuncInset::Write(FILE *file)
{
   fprintf(file, "\\%s ", name);
}

inline
void MathSpaceInset::Metrics()
{
   width = (space) ? space*2: 2;
   if (space>3) width *= 2;
   if (space==5) width *= 2;
   width += 4;
   ascent = 4; descent = 0;
}

inline
void MathSpaceInset::SetSpace(int sp)
{ 
   space = sp;
   Metrics();
}    

inline
bool MathBigopInset::GetLimits() const 
{  
   return (bool)(lims && (GetStyle()==LM_ST_DISPLAY)); 
} 

inline
void MathBigopInset::SetLimits(bool ls) 
{  
   lims = ls; 
} 

inline
bool MathDecorationInset::GetLimits(void) const
{ 
   return (bool)(deco==LM_underbrace||deco==LM_overbrace);
}    

#endif

