/*
 * Copyright (C) 2007 Tomasz Boczkowski <tboczkowski@onet.pl>
 *
 * This file is part of the KDE project "KBounce"
 *
 * KBounce 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.
 *
 * KBounce 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 KBounce; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#ifndef WALL_H
#define WALL_H

#include <KGameRenderedItem>

#include <QObject>
#include <KgSound>
#include "gameobject.h"

class KBounceRenderer;
class KBounceBoard;

/**
 * KGameRenderedItem representing a wall "under-construction"
 *
 * There are four walls in a board, each of which extends in
 * other direction: up, right, down or left
 */ 
class KBounceWall : public QObject, public KGameRenderedItem
{
    Q_OBJECT

    public:
        enum Direction { Up = 0, Down, Left, Right };

        /**
         * Constructor
         * @param dir is set in construction and does not change in gameplay
         * that means there will be no two walls extending in the same direction
         * in the same time
         */
        KBounceWall( Direction dir, KBounceRenderer* renderer, KBounceBoard* board );
        ~KBounceWall();

        /**
         * Changes object's state when collisions have been detected
         * Called once per frame before advance() and update()
         */
        void collide( KBounceCollision collision );
        /**
         * Performs various movement and state calculations non-related
         * to collision responses. Also updates m_boundingRect and 
         * m_nextBoundingRect. This method is called once per frame
         * after collide() and before update()
         */
        void goForward();
        /**
         * Updates object's pixmap and position on screen
         * Called once per frame after update()
         */
        void update();

        /**
         * Starts building wall beginning from tile specified by x and y
         * The direction has been specified in constructor
         */
        void build( int x, int y );
        /**
         * Returns the bounding rect that is expected for wall to
         * have in next frame. Collision in KBounceBoard are based on
         * the result of this method
         */
        QRectF nextBoundingRect() const;

        /**
         * Changes on-screen dimensions of the wall. 
         * Calculations are based on tile size, that is the on-screen
         * size of board's tile
         */
        void resize( const QSize& tileSize );

        /**
         * Set the wall velocity for wall filling speed.
         */
        void setWallVelocity(qreal velocity);

        /**
         * Load all sprites for top, down, left and right walls as well as for
         * the vertical and horizontal semi transparent bars drawn before a wall is
         * built.
         */
        void static loadSprites();

    signals:
        void finished( int left, int top, int right, int bottom );
        void died();

    private:
        /**
         * Returns true if rect2 intersects the edge at the end of wall
         * e.g for wall extending in direction Up this will be the upper
         * edge.
         */
        bool safeEdgeHit( const QRectF& rect2 ) const;
        /**
         * Helper function replacing emiting long finished signal
         * It also hides the wall and plays corresponding sound
         * If &param shorten is true the wall will be one unit in
         * direction &param dir shorter than normal 
         */
        void finish( bool shorten = false, Direction dir = Up);

        KBounceBoard *m_board;
        Direction m_dir;

        KgSound m_soundWallstart;
        KgSound m_soundReflect;

        QRectF m_boundingRect;
        QRectF m_nextBoundingRect;
        qreal m_wallVelocity;

        typedef struct {
            QPixmap wallEndLeft;
            QPixmap wallEndUp;
            QPixmap wallEndRight;
            QPixmap wallEndDown;
            QPixmap wallH;
            QPixmap wallV;

        } Sprites;
        static Sprites *s_sprites;

        static QSize s_tileSize;
        static KBounceRenderer *m_renderer;
};

#endif


