/***************************************************************************
 *   Copyright (C) 2004, 2007 by Kraschinski Arnold                        *
 *   arnold.kra67 at gmx dot de                                            *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   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.          *
 ***************************************************************************/
#ifndef JIGSAW_H_
#define JIGSAW_H_

#include <QLabel>
#include <QPixmap>
#include <QSize>

#define MAXPARTS_H  12
#define MAXPARTS_V  8

class QImage;
class QSvgRenderer;
class QPaintEvent;
class QScrollArea;

/**
 * The class is part of the Kverbos feedback classes. It present an image to the
 * user as a jigsaw puzzle. The user can solve exercises and gets points for 
 * correct answers. 
 *
 * @short a jigsaw, the user can uncover and cover parts and set new pictures
 * @author Kraschinski Arnold <arnold.kra67@gmx.de>
 * @version 2.00.00
 */
class Jigsaw : public QLabel
{
    Q_OBJECT
public:
    /** The contructor creats a jigsaw puzzle. It needs a path to an image and the
     *  information how many tiles per row and column should be created.
     *
     *  @param image the path to the image file
     *  @param hParts number of tiles in horizontal direction
     *  @param vParts number of tiles in vertical direction
     */
    Jigsaw ( QWidget* parent, QString image, int hParts, int vParts, QScrollArea* scrollArea );
    ~Jigsaw ();
    
    /** Load a new image file to the object. Cover all tiles.
     *
     *  @param image the path to the image file
     *  @param hParts number of tiles in horizontal direction
     *  @param vParts number of tiles in vertical direction
     */
    void load ( QString image, int hParts, int vParts );
    
    /** Get the jigsaw puzzle as a QPixmap. This is the image with all invisible tiles 
     *  covered.
     *
     *  @return the jigsaw puzzel with invisible parts as a QPixmap
     */
    QPixmap jigsaw ();
    
    /** Get a pointer to the Jigsaw image. The whole image unchanged.
     *
     *  @return a pointer to the jigsaw image.
     */
    QImage* getImage() { return m_image; };
    
    /** The image can be scaled to another dimension
      */
    void scaleImage( bool scale );
    
    /** Cover all tiles. That means all variables in the array m_visible
     *  are set to false.
     */
    void coverAll ();
    
    /** Marks the jigsaw as changed
     */
    void setChanged() { m_changed = true; };

protected:
    /** Paints the Jigsaw. The jigsaw is fetched from the m_image object.
     *  an transferred to the Jigsaw object using the QPixmap::fromImage() function.
     *  Afterwards the paintEvent funciton of the baseclass QLabel is called.
     *
     *  @param event The QPaintEvent that needs to be handled.
     */
    virtual void paintEvent ( QPaintEvent* event );
    
private:    
    /** Randomly on tile is selected an uncovered. The function returns true
     *  as long as a tile could be uncovered. it returns false when the jigsaw is
     *  already solved.
     *
     *  @return true, if a tile could be uncovered false if there aren't any uncoverd tiles left.
     */
    bool uncover ();
    

    
public slots:
    /** Uncover n tiles
     *
     * @param n number of tiles that should be uncoverd
     */
    void slotUncover( int n );
    
signals:
    void signalJigsawSolved();

private:
    /** This is the picture used for the jigsaw */
    QImage*             m_image;

    /** The QSvgRenderer is used to draw the tiles of the jigsaw */
    QSvgRenderer*       m_renderer;
    
    /** The information in how many tiles the jigsaw has been parted. */
    int                 m_hParts;
    int                 m_vParts;
    
    /** Is true if the image should be changed to another dimension.
      * False means the image isn't scaled. The default value is false. */
    bool                m_scale;

    /** The information which parts are uncovered */
    bool                m_visible [MAXPARTS_H] [MAXPARTS_V];
    
    /** If the jigsaw has recently been changed, the m_changed member is true.
     *  Changed means that a tile has been uncovered. If m_changed is false
     *  nothing has been changed.
     */
    bool                m_changed;
    
    /** If the jigsaw object gets the tast to uncover n tiles but there are
     *  less tiles left some points cannot be shown. In this case
     *  the rest is stored in m_pending. When the jigsaw is loaded with a new
     *  picture the tiles in m_pending are uncoverd at once.
     */
    int                 m_pending;
    
    /** A pointer to the QScrollArea that is the containr for the jigsaw */
    QScrollArea*        m_scrollArea;

public:
    /** The maximum number of parts in a row or a column of the puzzle */
    static const int MAXPARTS_HORIZONTICAL;
    static const int MAXPARTS_VERTICAL;
};

#endif // JIGSAW_H_
