/*
 * Copyright (C) 2010-2015 by Stephen Allewell
 * steve.allewell@gmail.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */


#ifndef Stitch_H
#define Stitch_H

#include <QDataStream>
#include <QPoint>
#include <QQueue>


class Stitch
{
public:
    enum Type {
        Delete = 0,
        TLQtr = 1,
        TRQtr = 2,
        BLQtr = 4,
        BTHalf = 6,
        TL3Qtr = 7,
        BRQtr = 8,
        TBHalf = 9,
        TR3Qtr = 11,
        BL3Qtr = 13,
        BR3Qtr = 14,
        Full = 15,
        TLSmallHalf = 65,
        TRSmallHalf = 66,
        BLSmallHalf = 68,
        BRSmallHalf = 72,
        TLSmallFull = 129,
        TRSmallFull = 130,
        BLSmallFull = 132,
        BRSmallFull = 136,
        FrenchKnot = 255
    };

    Stitch();
    Stitch(Stitch::Type, int);

    static const int version = 100;

    Stitch::Type    type;
    int     colorIndex;
};


QDataStream &operator<<(QDataStream &, const Stitch &);
QDataStream &operator>>(QDataStream &, Stitch &);


class StitchQueue : public QQueue<Stitch *>
{
public:
    StitchQueue();
    explicit StitchQueue(StitchQueue *);
    ~StitchQueue();

    int add(Stitch::Type, int);
    Stitch *find(Stitch::Type, int);
    int remove(Stitch::Type, int);

    static const int version = 100;
};


QDataStream &operator<<(QDataStream &, const StitchQueue &);
QDataStream &operator>>(QDataStream &, StitchQueue &);


class Backstitch
{
public:
    Backstitch();
    Backstitch(const QPoint &, const QPoint &, int);

    bool contains(const QPoint &) const;
    void move(int, int);
    void move(const QPoint &);

    static const int version = 100;

    QPoint  start;
    QPoint  end;
    int colorIndex;
};


QDataStream &operator<<(QDataStream &, const Backstitch &);
QDataStream &operator>>(QDataStream &, Backstitch &);


class Knot
{
public:
    Knot();
    Knot(const QPoint &, int);

    void move(int, int);
    void move(const QPoint &);

    static const int version = 100;

    QPoint  position;
    int colorIndex;
};


QDataStream &operator<<(QDataStream &, const Knot &);
QDataStream &operator>>(QDataStream &, Knot &);


const Stitch::Type stitchMap[][4] = {
    {
        Stitch::TLQtr,
        Stitch::TRQtr,
        Stitch::BLQtr,
        Stitch::BRQtr
    },
    {
        Stitch::TBHalf,
        Stitch::BTHalf,
        Stitch::BTHalf,
        Stitch::TBHalf
    },
    {
        Stitch::TL3Qtr,
        Stitch::TR3Qtr,
        Stitch::BL3Qtr,
        Stitch::BR3Qtr
    },
    {
        Stitch::Full,
        Stitch::Full,
        Stitch::Full,
        Stitch::Full
    },
    {
        Stitch::TLSmallHalf,
        Stitch::TRSmallHalf,
        Stitch::BLSmallHalf,
        Stitch::BRSmallHalf
    },
    {
        Stitch::TLSmallFull,
        Stitch::TRSmallFull,
        Stitch::BLSmallFull,
        Stitch::BRSmallFull
    }
};


#endif // Stitch_H
