/****************************************************************************
**
** This file is part of the LibreCAD project, a 2D CAD program
**
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file gpl-2.0.txt included in the
** packaging of this file.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
** This copyright notice MUST APPEAR in all copies of the script!
**
**********************************************************************/

#ifndef RS_H
#define RS_H

#include <qnamespace.h>
#include <qglobal.h>
#if QT_VERSION >= 0x050000
# include <QtPrintSupport/QPrinter>
#else
# include <qprinter.h>
#endif 

#define RS_TEST

#ifdef RS_TEST
#include <assert.h>
#endif

// Windoze XP can't handle the original MAX/MINDOUBLE's
#define RS_MAXDOUBLE 1.0E+10
#define RS_MINDOUBLE -1.0E+10


/**
 * Class namespace for various enums along with some simple
 * wrapper methods for converting the enums to the Qt
 * counterparts.
 *
 * @author Andrew Mustun
 */
class RS2 {
public:

    /**
     * Flags.
     */
    enum Flags {
        /** Flag for Undoables. */
        FlagUndone      = 1<<0,
        /** Entity Visibility. */
        FlagVisible     = 1<<1,
        /** Entity attribute (e.g. color) is defined by layer. */
        FlagByLayer     = 1<<2,
        /** Entity attribute (e.g. color) defined by block. */
        FlagByBlock     = 1<<3,
        /** Layer frozen. */
        FlagFrozen      = 1<<4,
        /** Layer frozen by default. */
        FlagDefFrozen   = 1<<5,
        /** Layer locked. */
        FlagLocked      = 1<<6,
        /** Used for invalid pens. */
        FlagInvalid     = 1<<7,
        /** Entity in current selection. */
        FlagSelected    = 1<<8,
        /** Polyline closed? */
        FlagClosed      = 1<<9,
        /** Flag for temporary entities (e.g. hatch) */
        FlagTemp        = 1<<10,
        /** Flag for processed entities (optcontour) */
        FlagProcessed   = 1<<11,
        /** Startpoint selected */
        FlagSelected1   = 1<<12,
        /** Endpoint selected */
        FlagSelected2   = 1<<13,
                /** Entity is highlighted temporarily (as a user action feedback) */
                FlagHighlighted = 1<<14
    };

    /**
     * Variable types used by RS_VariableDict and RS_Variable.
     */
    enum VariableType {
        VariableString,
        VariableInt,
        VariableDouble,
        VariableVector,
        VariableVoid
    };

    /**
     * File types. Used by file dialogs. Note: the extension might not
     * be enough to distinguish file types.
     */
    enum FormatType {
        FormatUnknown,       /**< Unknown / unsupported format. */
        FormatDXF1,          /**< QCad 1 compatibility DXF format. */
        FormatDXFRW,           /**< DXF format. v2007. */
        FormatDXFRW2004,           /**< DXF format. v2004. */
        FormatDXFRW2000,           /**< DXF format. v2000. */
        FormatDXFRW14,           /**< DXF format. v14. */
        FormatDXFRW12,           /**< DXF format. v12. */
#ifdef DWGSUPPORT
        FormatDWG,           /**< DWG format. */
#endif
        FormatLFF,           /**< LibreCAD Font File format. */
        FormatCXF,           /**< CAM Expert Font format. */
        FormatJWW,           /**< JWW Format type */
        FormatJWC            /**< JWC Format type */
    };

    /**
     * Entity types returned by the rtti() method
     */
    enum EntityType {
        EntityUnknown,      /**< Unknown */
        EntityContainer,    /**< Container */
        EntityBlock,        /**< Block (Group definition) */
        EntityFontChar,     /**< Font character */
        EntityInsert,       /**< Insert (Group instance) */
        EntityGraphic,      /**< Graphic with layers */
        EntityPoint,        /**< Point */
        EntityLine,         /**< Line */
        EntityPolyline,     /**< Polyline */
        EntityVertex,       /**< Vertex (part of a polyline) */
        EntityArc,          /**< Arc */
        EntityCircle,       /**< Circle */
        EntityEllipse,      /**< Ellipse */
        EntityHyperbola,      /**< Hyperbola */
        EntitySolid,        /**< Solid */
        EntityConstructionLine, /**< Construction line */
        EntityMText,         /**< Multi-line Text */
        EntityText,         /**< Single-line Text */
        EntityDimAligned,   /**< Aligned Dimension */
        EntityDimLinear,    /**< Linear Dimension */
        EntityDimRadial,    /**< Radial Dimension */
        EntityDimDiametric, /**< Diametric Dimension */
        EntityDimAngular,   /**< Angular Dimension */
        EntityDimLeader,    /**< Leader Dimension */
        EntityHatch,        /**< Hatch */
        EntityImage,        /**< Image */
        EntitySpline,       /**< Spline */
        EntityOverlayBox,    /**< OverlayBox */
        EntityPreview    /**< Preview Container */
    };

    static bool isContainer(const EntityType enType){
        switch(enType){
        case EntityPolyline:
        case EntityContainer:
        case EntitySpline:
            return true;
        default:
            return false;
        }
    }

    /**
     * Action types used by action factories.
     */
    enum ActionType {
        ActionNone,        /**< Invalid action id. */

        ActionDefault,

        ActionFileNew,
        ActionFileNewTemplate,
        ActionFileOpen,
        ActionFileSave,
        ActionFileSaveAs,
        ActionFileExport,
        ActionFileClose,
        ActionFilePrint,
        ActionFilePrintPreview,
        ActionFileQuit,

        ActionPrintPreview,

        ActionEditKillAllActions,
        ActionEditUndo,
        ActionEditRedo,
        ActionEditCut,
        ActionEditCutNoSelect,
        ActionEditCopy,
        ActionEditCopyNoSelect,
        ActionEditPaste,
        ActionOrderNoSelect,
        ActionOrderBottom,
        ActionOrderLower,
        ActionOrderRaise,
        ActionOrderTop,

        ActionViewStatusBar,
        ActionViewLayerList,
        ActionViewBlockList,
        ActionViewCommandLine,
        ActionViewLibrary,

        ActionViewPenToolbar,
        ActionViewOptionToolbar,
        ActionViewCadToolbar,
        ActionViewFileToolbar,
        ActionViewEditToolbar,
        ActionViewSnapToolbar,

        ActionViewGrid,
        ActionViewDraft,

        ActionZoomIn,
        ActionZoomOut,
        ActionZoomAuto,
        ActionZoomWindow,
        ActionZoomPan,
        ActionZoomRedraw,
        ActionZoomPrevious,

        ActionSelect,
        ActionSelectSingle,
        ActionSelectContour,
        ActionSelectWindow,
        ActionDeselectWindow,
        ActionSelectAll,
        ActionDeselectAll,
        ActionSelectIntersected,
        ActionDeselectIntersected,
        ActionSelectInvert,
        ActionSelectLayer,
        ActionSelectDouble,

        ActionDrawArc,
        ActionDrawArc3P,
        ActionDrawArcParallel,
        ActionDrawArcTangential,
        ActionDrawCircle,
        ActionDrawCircle2P,
        ActionDrawCircle3P,
        ActionDrawCircleCR,
        ActionDrawCircleParallel,
        ActionDrawCircleInscribe,
        ActionDrawCircleTan2_1P,
        ActionDrawCircleTan1_2P,
        ActionDrawCircleTan2,
        ActionDrawCircleTan3,

        ActionDrawEllipseArcAxis,
        ActionDrawEllipseAxis,
        ActionDrawEllipseFociPoint,
        ActionDrawEllipse4Points,
        ActionDrawEllipseCenter3Points,
        ActionDrawEllipseInscribe,

        ActionDrawHatch,
        ActionDrawHatchNoSelect,
        ActionDrawImage,
        ActionDrawLine,
        ActionDrawLineAngle,
        ActionDrawLineBisector,
        ActionDrawLineFree,
        ActionDrawLineHorVert,
        ActionDrawLineHorizontal,
        ActionDrawLineOrthogonal,
        ActionDrawLineOrthTan,
        ActionDrawLineParallel,
        ActionDrawLineParallelThrough,
        ActionDrawLinePolygonCenCor,
        ActionDrawLinePolygonCorCor,
        ActionDrawLineRectangle,
        ActionDrawLineRelAngle,
        ActionDrawLineTangent1,
        ActionDrawLineTangent2,
        ActionDrawLineVertical,
        ActionDrawMText,
        ActionDrawPoint,
        ActionDrawSpline,
        ActionDrawPolyline,
        ActionDrawText,

        ActionPolylineAdd,
        ActionPolylineAppend,
        ActionPolylineDel,
        ActionPolylineDelBetween,
        ActionPolylineTrim,
        ActionPolylineEquidistant,
        ActionPolylineSegment,

        ActionDimAligned,
        ActionDimLinear,
        ActionDimLinearVer,
        ActionDimLinearHor,
        ActionDimRadial,
        ActionDimDiametric,
        ActionDimAngular,
        ActionDimLeader,

        ActionModifyAttributes,
        ActionModifyAttributesNoSelect,
        ActionModifyDelete,
        ActionModifyDeleteNoSelect,
        ActionModifyDeleteQuick,
        ActionModifyDeleteFree,
        ActionModifyMove,
        ActionModifyMoveNoSelect,
        ActionModifyRotate,
        ActionModifyRotateNoSelect,
        ActionModifyScale,
        ActionModifyScaleNoSelect,
        ActionModifyMirror,
        ActionModifyMirrorNoSelect,
        ActionModifyMoveRotate,
        ActionModifyMoveRotateNoSelect,
		ActionModifyRevertDirection,
		ActionModifyRevertDirectionNoSelect,
        ActionModifyRotate2,
        ActionModifyRotate2NoSelect,
        ActionModifyEntity,
        ActionModifyTrim,
        ActionModifyTrim2,
        ActionModifyTrimAmount,
        ActionModifyCut,
        ActionModifyStretch,
        ActionModifyBevel,
        ActionModifyRound,
        ActionModifyOffset,
        ActionModifyOffsetNoSelect,

        ActionSnapFree,
        ActionSnapGrid,
        ActionSnapEndpoint,
        ActionSnapOnEntity,
        ActionSnapCenter,
        ActionSnapMiddle,
        ActionSnapDist,
        ActionSnapIntersection,
        ActionSnapIntersectionManual,

        ActionRestrictNothing,
        ActionRestrictOrthogonal,
        ActionRestrictHorizontal,
        ActionRestrictVertical,

        ActionSetRelativeZero,
        ActionLockRelativeZero,
        ActionUnlockRelativeZero,

        ActionInfoInside,
        ActionInfoDist,
        ActionInfoDist2,
        ActionInfoAngle,
        ActionInfoTotalLength,
        ActionInfoTotalLengthNoSelect,
        ActionInfoArea,

        ActionLayersDefreezeAll,
        ActionLayersFreezeAll,
        ActionLayersAdd,
        ActionLayersRemove,
        ActionLayersEdit,
        ActionLayersToggleView,
        ActionLayersToggleLock,
        ActionLayersTogglePrint,

        ActionBlocksDefreezeAll,
        ActionBlocksFreezeAll,
        ActionBlocksAdd,
        ActionBlocksRemove,
        ActionBlocksAttributes,
        ActionBlocksEdit,
        ActionBlocksSave,
        ActionBlocksInsert,
        ActionBlocksToggleView,
        ActionBlocksCreate,
        ActionBlocksCreateNoSelect,
        ActionBlocksExplode,
        ActionBlocksExplodeNoSelect,

        ActionModifyExplodeText,
        ActionModifyExplodeTextNoSelect,

        ActionLibraryInsert,

        ActionOptionsGeneral,
        ActionOptionsDrawing,

                ActionToolRegenerateDimensions,

                ActionScriptOpenIDE,
                ActionScriptRun,

#ifndef RS_NO_COMPLEX_ENTITIES
                ActionPARISDebugCreateContainer,
#endif

        /** Needed to loop through all actions */
        ActionLast
    };

    /**
    * Entity ending. Used for returning which end of an entity is ment.
     */
    enum Ending {
        EndingStart,    /**< Start point. */
        EndingEnd,      /**< End point. */
        EndingNone      /**< Neither. */
    };

    /**
     * Update mode for non-atomic entities that need to be updated when
     * they change. e.g. texts, inserts, ...
     */
    enum UpdateMode {
        NoUpdate,       /**< No automatic updates. */
        Update,         /**< Always update automatically when modified. */
                PreviewUpdate   /**< Update automatically but only for previews (quick update) */
    };

    /**
     * Drawing mode.
     */
    enum DrawingMode {
        ModeFull,       /**< Draw everything always detailed (default) */
        ModeAuto,       /**< Draw details when reasonable */
        ModePreview,    /**< Draw only in black/white without styles */
                ModeBW          /**< Black/white. Can be used for printing. */
    };

    /**
     * Undoable rtti.
     */
    enum UndoableType {
        UndoableUnknown,    /**< Unknown undoable */
        UndoableEntity,     /**< Entity */
        UndoableLayer       /**< Layer */
    };

    /**
     * Toolbar ID's.
     */
    enum ToolBarId {
        ToolBarMain,        /**< Main (menu). */
        ToolBarPoints,      /**< Points. */
        ToolBarLines,       /**< Lines. */
        ToolBarArcs,        /**< Arcs. */
        ToolBarCircles,     /**< Circles. */
        ToolBarEllipses,    /**< Ellipses. */
        ToolBarSplines,     /**< Splines. */
        ToolBarPolylines,   /**< Polylines. */
        ToolBarText,        /**< Text. */
        ToolBarDim,         /**< Dimensions. */
        ToolBarSnap,        /**< Snap. */
        ToolBarModify,      /**< Modify. */
        ToolBarSelect,      /**< Select. */
        ToolBarInfo,         /**< Information */
        ToolBarNone         /**< Invalid toolbar ID */
    };

    /**
     * Units.
     */
    enum Unit {
        None = 0,               /**< No unit (unit from parent) */
        Inch = 1,               /**< Inch */
        Foot = 2,               /**< Foot: 12 Inches */
        Mile = 3,               /**< Mile: 1760 Yards = 1609 m */
        Millimeter = 4,         /**< Millimeter: 0.001m */
        Centimeter = 5,         /**< Centimeter: 0.01m */
        Meter = 6,              /**< Meter */
        Kilometer = 7,          /**< Kilometer: 1000m */
        Microinch = 8,          /**< Microinch: 0.000001 */
        Mil = 9,                /**< Mil = 0.001 Inch*/
        Yard = 10,              /**< Yard: 3 Feet */
        Angstrom = 11,          /**< Angstrom: 10^-10m  */
        Nanometer = 12,         /**< Nanometer: 10^-9m  */
        Micron = 13,            /**< Micron: 10^-6m  */
        Decimeter = 14,         /**< Decimeter: 0.1m */
        Decameter = 15,         /**< Decameter: 10m */
        Hectometer = 16,        /**< Hectometer: 100m */
        Gigameter = 17,         /**< Gigameter: 1000000m */
        Astro = 18,             /**< Astro: 149.6 x 10^9m */
        Lightyear = 19,         /**< Lightyear: 9460731798 x 10^6m */
        Parsec = 20,            /**< Parsec: 30857 x 10^12 */

        LastUnit = 21           /**< Used to iterate through units */
    };


    /**
     * Format for length values.
     */
    enum LinearFormat {
        /** Scientific (e.g. 2.5E+05) */
        Scientific,
        /** Decimal (e.g. 9.5)*/
        Decimal,
        /** Engineering (e.g. 7' 11.5")*/
        Engineering,
        /** Architectural (e.g. 7'-9 1/8")*/
        Architectural,
        /** Fractional (e.g. 7 9 1/8) */
        Fractional
    };

    /**
     * Angle Units.
     */
    enum AngleUnit {
        Deg,               /**< Degrees */
        Rad,               /**< Radians */
        Gra                /**< Gradians */
    };

    /**
     * Display formats for angles.
     */
    enum AngleFormat {
        /** Degrees with decimal point (e.g. 24.5�) */
        DegreesDecimal,
        /** Degrees, Minutes and Seconds (e.g. 24�30'5'') */
        DegreesMinutesSeconds,
        /** Gradians with decimal point (e.g. 390.5)*/
        Gradians,
        /** Radians with decimal point (e.g. 1.57)*/
        Radians,
        /** Surveyor's units */
        Surveyors
    };

    /**
     * Enum of levels of resolving when iterating through an entity tree.
     */
    enum ResolveLevel {
        /** Groups are not resolved */
        ResolveNone,
        /**
        * Resolve all but not Inserts.
        */
        ResolveAllButInserts,
        /**
         * Resolve all but not Text or MText.
         */
        ResolveAllButTexts,
        /**
         * Resolve no text or images, added as a quick fix for bug#422
         */
        ResolveAllButTextImage,
        /**
         * all Entity Containers are resolved
         * (including Texts, Polylines, ...)
         */
        ResolveAll
    };

    /**
     * Direction used for scrolling actions.
     */
    enum Direction {
        Up, Left, Right, Down
    };

    /**
     * Vertical alignments.
     */
//    enum VAlign {
//        VAlignTop,      /**< Top. */
//        VAlignMiddle,   /**< Middle */
//        VAlignBottom    /**< Bottom */
//    };

    /**
     * Horizontal alignments.
     */
//    enum HAlign {
//        HAlignLeft,     /**< Left */
//        HAlignCenter,   /**< Centered */
//        HAlignRight     /**< Right */
//    };

    /**
     * Text drawing direction.
     */
//    enum TextDrawingDirection {
//        LeftToRight,     /**< Left to right */
//        TopToBottom,     /**< Top to bottom */
//        ByStyle          /**< Inherited from associated text style */
//    };

    /**
     * Line spacing style for texts.
     */
//    enum TextLineSpacingStyle {
//        AtLeast,        /**< Taller characters will override */
//        Exact           /**< Taller characters will not override */
//    };

    /**
     * Leader path type.
     */
    enum LeaderPathType {
        Straight,      /**< Straight line segments */
        Spline         /**< Splines */
    };

    /**
     * Direction for zooming actions.
     */
    enum ZoomDirection {
        In, Out
    };

    /**
     * Axis specification for zooming actions.
     */
    enum Axis {
        OnlyX, OnlyY, Both
    };

    /**
     * Crosshair type
     */
    enum CrosshairType {
        LeftCrosshair,         /**< Left type isometric Crosshair */
        TopCrosshair,         /**< Top type isometric Crosshair */
        RightCrosshair,         /**< Right type isometric Crosshair */
        OrthogonalCrosshair         /**< Orthogonal Crosshair */
    };

    /**
     * Snapping modes
     */
    enum SnapMode {
        SnapFree,         /**< Free positioning */
        SnapGrid,         /**< Snap to grid points */
        SnapEndpoint,     /**< Snap to endpoints */
        SnapMiddle,       /**< Snap to middle points */
        SnapCenter,       /**< Snap to centers */
        SnapOnEntity,     /**< Snap to the next point on an entity */
        SnapDist,         /**< Snap to points with a distance to an endpoint */
        SnapIntersection, /**< Snap to intersection */
        SnapIntersectionManual  /**< Snap to intersection manually */
    };

    /**
     * Snap restrictions
     */
    enum SnapRestriction {
        RestrictNothing,        /**< No restriction to snap mode */
        RestrictHorizontal,     /**< Restrict to 0,180 degrees */
        RestrictVertical,       /**< Restrict to 90,270 degrees */
        RestrictOrthogonal      /**< Restrict to 90,180,270,0 degrees */
    };

    /**
     * Enum of line styles:
     */
    enum LineType {
        NoPen = 0,            /**< No line at all. */
        SolidLine = 1,        /**< Normal line. */

        DotLine = 2,          /**< Dotted line. */
        DotLine2 = 3,         /**< Dotted line small. */
        DotLineX2 = 4,        /**< Dotted line large. */

        DashLine = 5,         /**< Dashed line. */
        DashLine2 = 6,        /**< Dashed line small. */
        DashLineX2 = 7,       /**< Dashed line large. */

        DashDotLine = 8,      /**< Alternate dots and dashes. */
        DashDotLine2 = 9,     /**< Alternate dots and dashes small. */
        DashDotLineX2 = 10,   /**< Alternate dots and dashes large. */

        DivideLine = 11,      /**< dash, dot, dot. */
        DivideLine2 = 12,     /**< dash, dot, dot small. */
        DivideLineX2 = 13,    /**< dash, dot, dot large. */

        CenterLine = 14,      /**< dash, small dash. */
        CenterLine2 = 15,     /**< dash, small dash small. */
        CenterLineX2 = 16,    /**< dash, small dash large. */

        BorderLine = 17,      /**< dash, dash, dot. */
        BorderLine2 = 18,     /**< dash, dash, dot small. */
        BorderLineX2 = 19,    /**< dash, dash, dot large. */

        LineByLayer = -1,     /**< Line type defined by layer not entity */
        LineByBlock = -2      /**< Line type defined by block not entity */
    };

    /**
     * Wrapper for Qt
     */
    static Qt::PenStyle rsToQtLineType(RS2::LineType t) {
        switch (t) {
        case NoPen:
            return Qt::NoPen;
            break;
        case SolidLine:
            return Qt::SolidLine;
            break;
        case DotLine:
        case DotLine2:
        case DotLineX2:
            return Qt::DotLine;
            break;
        case DashLine:
        case DashLine2:
        case DashLineX2:
            return Qt::DashLine;
            break;
        case DashDotLine:
        case DashDotLine2:
        case DashDotLineX2:
            return Qt::DashDotLine;
            break;
        case DivideLine:
        case DivideLine2:
        case DivideLineX2:
            return Qt::DashDotDotLine;
            break;
        case CenterLine:
        case CenterLine2:
        case CenterLineX2:
            return Qt::DashDotLine;
            break;
        case BorderLine:
        case BorderLine2:
        case BorderLineX2:
            return Qt::DashDotLine;
            break;
        case LineByLayer:
        case LineByBlock:
        default:
            return Qt::SolidLine;
            break;
        }
        return Qt::SolidLine;
    }

    /**
     * Wrapper for Qt.
     */
    static RS2::LineType qtToRsPenStyle(Qt::PenStyle s) {
        switch (s) {
        case Qt::NoPen:
            return NoPen;
        case Qt::SolidLine:
            return SolidLine;
            break;
        case Qt::DashLine:
            return DashLine;
            break;
        case Qt::DotLine:
            return DotLine;
            break;
        case Qt::DashDotLine:
            return DashDotLine;
            break;
        case Qt::DashDotDotLine:
            return DivideLine;
            break;
        default:
            return SolidLine;
            break;
        }
        return SolidLine;
    }

    /**
     * \brief Struct that stores a line type pattern (e.g. dash dot dot).
     */
    struct LineTypePatternStruct {
        double* pattern;
        int num;
    }
    LineTypePattern;

    /**
     * Enum of line widths:
     */
    enum LineWidth {
        Width00 = 0,       /**< Width 1.  (0.00mm) */
        Width01 = 5,       /**< Width 2.  (0.05mm) */
        Width02 = 9,       /**< Width 3.  (0.09mm) */
        Width03 = 13,      /**< Width 4.  (0.13mm) */
        Width04 = 15,      /**< Width 5.  (0.15mm) */
        Width05 = 18,      /**< Width 6.  (0.18mm) */
        Width06 = 20,      /**< Width 7.  (0.20mm) */
        Width07 = 25,      /**< Width 8.  (0.25mm) */
        Width08 = 30,      /**< Width 9.  (0.30mm) */
        Width09 = 35,      /**< Width 10. (0.35mm) */
        Width10 = 40,      /**< Width 11. (0.40mm) */
        Width11 = 50,      /**< Width 12. (0.50mm) */
        Width12 = 53,      /**< Width 13. (0.53mm) */
        Width13 = 60,      /**< Width 14. (0.60mm) */
        Width14 = 70,      /**< Width 15. (0.70mm) */
        Width15 = 80,      /**< Width 16. (0.80mm) */
        Width16 = 90,      /**< Width 17. (0.90mm) */
        Width17 = 100,     /**< Width 18. (1.00mm) */
        Width18 = 106,     /**< Width 19. (1.06mm) */
        Width19 = 120,     /**< Width 20. (1.20mm) */
        Width20 = 140,     /**< Width 21. (1.40mm) */
        Width21 = 158,     /**< Width 22. (1.58mm) */
        Width22 = 200,     /**< Width 23. (2.00mm) */
        Width23 = 211,     /**< Width 24. (2.11mm) */
        WidthByLayer = -1, /**< Line width defined by layer not entity. */
        WidthByBlock = -2, /**< Line width defined by block not entity. */
        WidthDefault = -3  /**< Line width defaults to the predefined line width. */
    };

    /**
     * Wrapper for Qt
     */
    /*
       static int qw(RS2::LineWidth w) {
           switch (w) {
           case Width00:
               return 1;  // 0 is more accurate but quite slow
               break;
           case WidthByLayer:
           case WidthByBlock:
           case WidthDefault:
               return 1;
               break;
           case Width01:
           case Width02:
           case Width03:
           case Width04:
           case Width05:
           case Width06:
           case Width07:
           case Width08:
               return 1;
               break;
           case Width09:
           case Width10:
               return 3;
               break;
           case Width11:
               return 4;
               break;
           case Width12:
           case Width13:
               return 5;
               break;
           case Width14:
               return 6;
               break;
           case Width15:
               return 7;
               break;
           case Width16:
               return 8;
               break;
           case Width17:
               return 9;
               break;
           case Width18:
           case Width19:
               return 10;
               break;
           case Width20:
               return 12;
               break;
           case Width21:
           case Width22:
           case Width23:
           //case Width24:
               return 14;
               break;
           default:
               return (int)w;
               break;
           }
           return (int)w;
       }
    */

    /**
     * Wrapper for Qt
     */
    static LineWidth intToLineWidth(int w) {
                if (w==-3) {
                        return WidthDefault;
                } else if (w==-2) {
                        return WidthByBlock;
                } else if (w==-1) {
                        return WidthByLayer;
                } else if (w<3) {
                        return Width00;
                } else if (w<8) {
                        return Width01;
                } else if (w<12) {
                        return Width02;
                } else if (w<14) {
                        return Width03;
                } else if (w<17) {
                        return Width04;
                } else if (w<19) {
                        return Width05;
                } else if (w<23) {
                        return Width06;
                } else if (w<28) {
                        return Width07;
                } else if (w<33) {
                        return Width08;
                } else if (w<38) {
                        return Width09;
                } else if (w<46) {
                        return Width10;
                } else if (w<52) {
                        return Width11;
                } else if (w<57) {
                        return Width12;
                } else if (w<66) {
                        return Width13;
                } else if (w<76) {
                        return Width14;
                } else if (w<86) {
                        return Width15;
                } else if (w<96) {
                        return Width16;
                } else if (w<104) {
                        return Width17;
                } else if (w<114) {
                        return Width18;
                } else if (w<131) {
                        return Width19;
                } else if (w<150) {
                        return Width20;
                } else if (w<180) {
                        return Width21;
                } else if (w<206) {
                        return Width22;
                } else {
                        return Width23;
                }
    }

    /**
     * Enum of cursor types.
     */
    enum CursorType {
        ArrowCursor,          /**< ArrowCursor - standard arrow cursor. */
        UpArrowCursor,        /**< UpArrowCursor - upwards arrow. */
        CrossCursor,          /**< CrossCursor - crosshair. */
        WaitCursor,           /**< WaitCursor - hourglass/watch. */
        IbeamCursor,          /**< IbeamCursor - ibeam/text entry. */
        SizeVerCursor,        /**< SizeVerCursor - vertical resize. */
        SizeHorCursor,        /**< SizeHorCursor - horizontal resize. */
        SizeBDiagCursor,      /**< SizeBDiagCursor - diagonal resize (/). */
        SizeFDiagCursor,      /**< SizeFDiagCursor - diagonal resize (\). */
        SizeAllCursor,        /**< SizeAllCursor - all directions resize. */
        BlankCursor,          /**< BlankCursor - blank/invisible cursor. */
        SplitVCursor,         /**< SplitVCursor - vertical splitting. */
        SplitHCursor,         /**< SplitHCursor - horziontal splitting. */
        PointingHandCursor,   /**< PointingHandCursor - a pointing hand. */
        ForbiddenCursor,      /**< ForbiddenCursor - a slashed circle. */
        WhatsThisCursor,      /**< WhatsThisCursor - an arrow with a ?. */
        OpenHandCursor,       /**< Qt OpenHandCursor */
        ClosedHandCursor,       /**< Qt ClosedHandCursor */
        CadCursor,            /**< CadCursor - a bigger cross. */
        DelCursor,            /**< DelCursor - cursor for choosing entities */
        SelectCursor,         /**< SelectCursor - for selecting single entities */
        MagnifierCursor,      /**< MagnifierCursor - a magnifying glass. */
        MovingHandCursor      /**< Moving hand - a little flat hand. */
    };

    /**
     * Wrapper for Qt.
     */
    static Qt::CursorShape rsToQtCursorType(RS2::CursorType t) {
        switch (t) {
        case ArrowCursor:
            return Qt::ArrowCursor;
        case UpArrowCursor:
            return Qt::UpArrowCursor;
        case CrossCursor:
            return Qt::CrossCursor;
        case WaitCursor:
            return Qt::WaitCursor;
        case IbeamCursor:
            return Qt::IBeamCursor;
        case SizeVerCursor:
            return Qt::SizeVerCursor;
        case SizeHorCursor:
            return Qt::SizeHorCursor;
        case SizeBDiagCursor:
            return Qt::SizeBDiagCursor;
        case SizeFDiagCursor:
            return Qt::SizeFDiagCursor;
        case SizeAllCursor:
            return Qt::SizeAllCursor;
        case BlankCursor:
            return Qt::BlankCursor;
        case SplitVCursor:
            return Qt::SplitVCursor;
        case SplitHCursor:
            return Qt::SplitHCursor;
        case PointingHandCursor:
            return Qt::PointingHandCursor;
        case OpenHandCursor:
            return Qt::OpenHandCursor;
        case ClosedHandCursor:
            return Qt::ClosedHandCursor;
        case ForbiddenCursor:
            return Qt::ForbiddenCursor;
        case WhatsThisCursor:
            return Qt::WhatsThisCursor;
        default:
            return Qt::ArrowCursor;
        }
    }

    /**
     * Paper formats.
     */
    enum PaperFormat {
        Custom,
                Letter,
                Legal,
                Executive,
        A0,
                A1,
                A2,
                A3,
                A4,
                A5,
                A6,
                A7,
                A8,
                A9,
        B0,
                B1,
                B2,
                B3,
                B4,
                B5,
                B6,
                B7,
                B8,
                B9,
                B10,
        C5E,
                Comm10E,
        DLE,
                Folio,
                //Ledger,
                Tabloid,
        Arch_A,
        Arch_B,
        Arch_C,
        Arch_D,
        Arch_E,
        Arch_E1,
        Arch_E2,
        Arch_E3,

                NPageSize
        };

    /**
     * Wrapper for Qt.
     */
    static QPrinter::PageSize rsToQtPaperFormat(RS2::PaperFormat f) {
                QPrinter::PageSize ret;

                switch (f) {
        case Custom:
                        ret = QPrinter::Custom;
                        break;
                case Letter:
                        ret = QPrinter::Letter;
                        break;
                case Legal:
                        ret = QPrinter::Legal;
                        break;
                case Executive:
                        ret = QPrinter::Executive;
                        break;
                case A0:
                        ret = QPrinter::A0;
                        break;
                case A1:
                        ret = QPrinter::A1;
                        break;
                case A2:
                        ret = QPrinter::A2;
                        break;
                case A3:
                        ret = QPrinter::A3;
                        break;
                default:
                case A4:
                        ret = QPrinter::A4;
                        break;
                case A5:
                        ret = QPrinter::A5;
                        break;
                case A6:
                        ret = QPrinter::A6;
                        break;
                case A7:
                        ret = QPrinter::A7;
                        break;
                case A8:
                        ret = QPrinter::A8;
                        break;
                case A9:
                        ret = QPrinter::A9;
                        break;
                case B0:
                        ret = QPrinter::B0;
                        break;
                case B1:
                        ret = QPrinter::B1;
                        break;
                case B2:
                        ret = QPrinter::B2;
                        break;
                case B3:
                        ret = QPrinter::B3;
                        break;
                case B4:
                        ret = QPrinter::B4;
                        break;
                case B5:
                        ret = QPrinter::B5;
                        break;
                case B6:
                        ret = QPrinter::B6;
                        break;
                case B7:
                        ret = QPrinter::B7;
                        break;
                case B8:
                        ret = QPrinter::B8;
                        break;
                case B9:
                        ret = QPrinter::B9;
                        break;
                case B10:
                        ret = QPrinter::B10;
                        break;
                case C5E:
                        ret = QPrinter::C5E;
                        break;
                case Comm10E:
                        ret = QPrinter::Comm10E;
                        break;
        case DLE:
                        ret = QPrinter::DLE;
                        break;
                case Folio:
                        ret = QPrinter::Folio;
                        break;
                //case Ledger:
                //	ret = QPrinter::Ledger;
                //	break;
                case Tabloid:
                        ret = QPrinter::Tabloid;
                        break;
                case NPageSize:
                        ret = QPrinter::NPageSize;
                        break;
                }

                return ret;
        }

        /**
         * Items that can be put on a overlay, teh items are rendered in this order. Best is to leave snapper as last so
         * it always shows up
         */
        enum OverlayGraphics {
                ActionPreviewEntity, // Action Entities
                Snapper // Snapper
        };

        //Different re-draw methods to speed up rendering of the screen
        enum RedrawMethod {
                RedrawNone = 0,
                RedrawGrid = 1,
                RedrawOverlay = 2,
                RedrawDrawing = 4,
                RedrawAll = 0xffff
        };

        /**
         * Text drawing direction.
         */
        enum TextLocaleDirection {
            locLeftToRight,     /** Left to right **/
            locRightToLeft      /** Right to Left **/
        };

};

#endif
