/***************************************************************************
                          board.h  -  description
                             -------------------
    begin                : Thu Aug 17 2000
    copyright            : (C) 2000 by Waldemar Baraldi
    email                : baraldi@lacasilla.com.ar
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 BOARD_H
#define BOARD_H

#include "animatedcanvas.h"

enum BoardState {Playing, OverLost, OverWon};
enum BackgroundType {WallpaperBackground, MosaicBackground};

static const int BoardColumns=9;
static const int BoardRows=8;

class Board;

#include "list.h"
#include "pipe.h"
#include "pointer.h"
#include "entry.h"
#include "exit.h"
#include "tank.h"
#include "background.h"


class Board: public AnimatedCanvas{

  public:

    static const int TankX=88;
    static const int TankY=0;

    Board();
    virtual ~Board();

    int width();

    int height();

    /** Setea la cantidad de ticks hasta comenzar
    a avanzar el flujo.*/
    void setStartDelay(int delay);

    /** Asigna la entrada del flujo.*/
    //void setEntry(Entry * entry, int row, int column);
    void setEntry(Entry * entry, int row, int column);

    /** Asigna la salida del flujo.*/
    //void setExit(Exit * exit, int row, int column);
    void setExit(Exit * exit, int row, int column);

    /** Retorna true si el pipe en row, column es removible.*/
    bool isRemovable(int row, int column);

    /** Asigna pipe a la posicion row,column. Si las coordenadas son
        invalidas, el resultado es indefinido. pipe no debe ser NULL.*/
    void setPipe(Pipe * pipe, int row, int column);

    /** Retorna el pipe en la posicion. Si las coordenadas no son
        validas, el resultado es indefinido.*/
    Pipe * getPipe(int row, int column);


    /** Retorna el estado del board.*/
    BoardState getState();

    /** Retorna la cantidad de pipes que son necesarios para completar el nivel.*/
    unsigned int getRequired();

    /** Retorna la cantiad de pipes que todavá faltan para completar el nivel.*/
    unsigned int getStillRequired();

    /** Agrega el puntero en la posicion que tenga.*/
    void addPointer(Pointer * p);

    /** Quita el puntero del board.*/
    void removePointer(Pointer * p);

   /** Mueve el puntero de posicion a row, column.*/
    void movePointer(Pointer *p, int row, int column);

    void setPos(int x, int y);

    void setSpeed(int amount);

    void setMaxSpeed();

    void setRequired(unsigned int value);

    void setBackgroundType(BackgroundType type);

    /** Señaliza el avance del líquido.*/
    void tick();

    void paint(VideoManager * vm);

  protected:

    unsigned int countStillRequired();

    BackgroundType background_type;
    Background * background;

    List * lps;

    Pipe * board[BoardRows][BoardColumns];

    Tank * tank;

    bool changes[BoardRows][BoardColumns];
    bool paint_all;

//    Image * background;

    int flow_row, flow_column;

    Pipe * entry;
    Pipe * exit;

    Pipe * last;
    int last_row, last_column;

    int entry_row;
    int entry_column;

    int start_delay;
    int tick_amount;

    CardinalPoint actual_output;
    CardinalPoint actual_input;

    BoardState state;

    unsigned int required;
    unsigned int still_required;
    bool required_changed;
};

#endif


