/* This file is part of the KDE project
   Copyright (C) 2003 Ulrich Kuettler <ulrich.kuettler@gmx.de>
   Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>

   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; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#ifndef FONTSTYLE_H
#define FONTSTYLE_H

#include <tqstring.h>
#include <tqfont.h>

#include "contextstyle.h"
#include "kformuladefs.h"
#include "symboltable.h"


KFORMULA_NAMESPACE_BEGIN

class Artwork;
class SymbolTable;


/**
 * Base class for all supported font styles.
 */
class FontStyle {
public:
    ~FontStyle() {}

    /**
     * lazy init support. Needs to be run before anything else.
     * @param install if true fonts may be installed if needed
     */
    bool init( ContextStyle* context, bool install = true );

    /// the table for ordinary symbols (those that have a unicode value)
    const SymbolTable* symbolTable() const { return &m_symbolTable; }
    SymbolTable* symbolTable() { return &m_symbolTable; }

    Artwork* createArtwork(SymbolType type = EmptyBracket) const;

    static TQStringList missingFonts( bool install = true );

    static bool m_installed;

    static void testFont( TQStringList& missing, const TQString& fontName );

private:

    static TQStringList missingFontsInternal();
    static void installFonts();

    SymbolTable m_symbolTable;

};

const TQChar spaceChar = 0x0020;
const TQChar leftParenthesisChar = 0x0028;
const TQChar rightParenthesisChar = 0x0029;
const TQChar leftSquareBracketChar = 0x005B;
const TQChar rightSquareBracketChar = 0x005D;
const TQChar leftCurlyBracketChar = 0x007B;
const TQChar verticalLineChar = 0x007C;
const TQChar rightCurlyBracketChar = 0x007D;
const TQChar leftAngleBracketChar = 0x2329;
const TQChar rightAngleBracketChar = 0x232A;
const TQChar slashChar = 0x002F;
const TQChar backSlashChar = 0x005C;
const TQChar integralChar = 0x222B;
const TQChar summationChar = 0x2211;
const TQChar productChar = 0x220F;
const TQChar applyFunctionChar = 0x2061;
const TQChar invisibleTimes = 0x2062;
const TQChar invisibleComma = 0x2063;

extern const TQChar leftRoundBracket[];
extern const TQChar leftSquareBracket[];
extern const TQChar leftCurlyBracket[];

extern const TQChar leftLineBracket[];
extern const TQChar rightLineBracket[];

extern const TQChar rightRoundBracket[];
extern const TQChar rightSquareBracket[];
extern const TQChar rightCurlyBracket[];

/*
 * A piece of art that may be used by any element.
 */
class Artwork {
public:

    Artwork(SymbolType type = EmptyBracket);
    virtual ~Artwork() {}

    virtual void calcSizes( const ContextStyle& style,
                            ContextStyle::TextStyle tstyle,
							double factor,
                            luPt parentSize );
    virtual void calcSizes( const ContextStyle& style,
                            ContextStyle::TextStyle tstyle,
							double factor );

    virtual void draw( TQPainter& painter, const LuPixelRect& r,
                       const ContextStyle& context,
                       ContextStyle::TextStyle tstyle,
					   StyleAttributes& style,
					   luPt parentSize, const LuPixelPoint& origin );
    virtual void draw( TQPainter& painter, const LuPixelRect& r,
                       const ContextStyle& context,
                       ContextStyle::TextStyle tstyle,
					   StyleAttributes& style,
                       const LuPixelPoint& parentOrigin );

    luPixel getWidth() const { return size.width(); }
    luPixel getHeight() const { return size.height(); }

    void setWidth( luPixel width ) { size.setWidth(width); }
    void setHeight( luPixel height ) { size.setHeight(height); }

    luPixel getBaseline() const { return baseline; }
    void setBaseline( luPixel line ) { baseline = line; }

    luPixel getX() const { return point.x(); }
    luPixel getY() const { return point.y(); }

    void setX( luPixel x ) { point.setX( x ); }
    void setY( luPixel y ) { point.setY( y ); }

    SymbolType getType() const { return type; }
    void setType(SymbolType t) { type = t; }

    virtual bool isNormalChar() const { return getBaseline() != -1 && ( cmChar == -1 ); }

    virtual double slant() const { return 0; }

protected:

    void calcCharSize( const ContextStyle& style, luPt height, TQChar ch );
    void drawCharacter( TQPainter& painter, const ContextStyle& style,
                        luPixel x, luPixel y, luPt height, TQChar ch );

    void calcCharSize( const ContextStyle& style, TQFont f, luPt height, TQChar c );
    void drawCharacter( TQPainter& painter, const ContextStyle& style,
                        TQFont f,
                        luPixel x, luPixel y, luPt height, uchar c );

    void calcRoundBracket( const ContextStyle& style, const TQChar chars[], luPt height, luPt charHeight );
    void calcCurlyBracket( const ContextStyle& style, const TQChar chars[], luPt height, luPt charHeight );

    void drawBigRoundBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[], luPixel x, luPixel y, luPt charHeight );
    void drawBigCurlyBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[], luPixel x, luPixel y, luPt charHeight );

private:

    LuPixelSize size;
    LuPixelPoint point;

    /**
     * Used if we are a character.
     */
    luPixel baseline;

    SymbolType type;

    bool calcCMDelimiterSize( const ContextStyle& context, uchar c,
                              luPt fontSize, luPt parentSize );
    void calcLargest( const ContextStyle& context, uchar c, luPt fontSize );
    void drawCMDelimiter( TQPainter& painter, const ContextStyle& style,
                          luPixel x, luPixel y, luPt height );

    short cmChar;
};


KFORMULA_NAMESPACE_END

#endif
