/*

Firestorm
by Brent P. Newhall 

 */

#include <gui/window.h>
#include <gui/view.h>
#include <gui/rect.h>
#include <util/application.h>
#include <vector>#include #include 
#include <util/thread.h>
#include <util/message.h>
#include <storage/file.h>
#include <storage/filereference.h>
#include <gui/image.h>
#include <gui/imageview.h>
#include <gui/stringview.h>
#include <media/soundplayer.h>
#include <fstream>
#include <iostream>
using namespace os;




#ifndef FIRESTORM
#define FIRESTORM




const unsigned int NUM_STARS = 250;
const unsigned int FIRING_BOTH_BULLETS = 100;

const unsigned int MSG_HEARTBEAT         = 1001;
const unsigned int MSG_FIRE_ENEMY_BULLET = 1002;
const unsigned int MSG_INCREMENT_SCORE   = 1003;
const unsigned int MSG_CHANGE_HEALTH     = 1004;
const unsigned int MSG_LEVEL_COMPLETE    = 1005;

const unsigned int BULLET_SMALL = 2001;
const unsigned int BULLET_WAVE  = 2002;

const unsigned int RED = 1;
const unsigned int YELLOW = 2;

const unsigned int WEAPON_SMALL = 1;
const unsigned int WEAPON_BIG   = 2;
const unsigned int WEAPON_WAVE  = 3;

extern Window *window;




// ---------- Utilities




float calc_float_number( const float number_part1, const float number,
                         bool is_negative );
std::vector<loat>* parse_line( const char * line );




// ---------- Heartbeat Thread




class HeartbeatThread : public Thread
    {
    public:
        HeartbeatThread() : Thread( "HeartbeatThread", LOW_PRIORITY ) { }
        int32 Run()
            {
            while( 1 == 1 )
                {
                Delay( 1000 ); /* Pause for one microsecond. */
                window->PostMessage( new Message( MSG_HEARTBEAT ), window );
                }
            return( 0 );
            }
    };




// ---------- Star




class Star : public Point
    {
    public:
        Star();
        void PlaceRandomly( void );
        unsigned int depth;
    };





// ---------- Bullet




class Bullet
    {
    public:
        Bullet();
        Bullet( float x, float y );
        Color32_s getColor( void )
        {    if( color == RED )  {  return Color32_s( 250, 0, 0 );  }
            else  {  return Color32_s( 250, 250, 0 );  }  }
        void update( void );
        unsigned int size;
        unsigned int color;
        Rect location;
        Point velocity;
        unsigned int heartbeat;
        void sync( void );
    };




// ---------- Player




class Player
    {
    public:
        Player();
        void setColor( unsigned int inColor );
        unsigned int getColor( void )  {  return color;  }
        void move( float xDelta, float yDelta );
        Point getLocation( void )  {  return location;  }
        Rect getBounds( void )  {  return boundary;  }
        void setBounds( float inLeft, float inTop, float inRight, float inBottom );
        void draw( View *drawingView );
        static const unsigned int RED = 1;
        static const unsigned int YELLOW = 2;
    private:
        unsigned int color;
        BitmapImage *image;
        BitmapImage staticImages[2];
        Point location;
        Rect boundary;
    };




// ---------- Enemy




class EnemyMovementEvent
    {
    public:
        EnemyMovementEvent();
        unsigned int time;
        Point velocity;
    };




class Enemy
    {
    public:
        Enemy();
        void SetPath( std::vector<loat>*pathNumbers );
        void setType( unsigned int inType );
        void addDamage( unsigned int damage );
        int getHealth( void )  {  return health;  }
        void update( void );
        unsigned int type;
        BitmapImage *image;
        Rect location;
        Point velocity;
        float direction;
        unsigned int color;
        unsigned int pathTicks;
        std::vector<nemyMovementEvent>movements;
    private:
        unsigned int heartbeat;
        unsigned int nextMovement;
        int health;
    };




// ---------- Event Queue




class LevelEvent
    {
    public:
        LevelEvent();
        int operator<( const LevelEvent &x ) const
        {  return( this->time < x.time );  }
        unsigned int time;
        float location;
        unsigned int enemyType;
        String path;
        unsigned int color;
    };




class LevelEventQueue
    {
    public:
        LevelEventQueue();
        status_t set( String levelName );
        std::vector<evelEvent *> events;
    };





// ---------- Enemy Manager




class EnemyManager
    {
    public:
        EnemyManager();
        status_t set( String levelName );
        status_t heartbeat( View *drawingView, Point playerLocation );
        unsigned int numOnscreenEnemies( void )  {  return enemies.size();  }
        void addBullet( float x, float y, float xVelocity, float yVelocity, unsigned int color, unsigned int size );
        void setWindow( Window *inWindow )  {  mainWindow = inWindow;  }
        friend class FirestormTest;
    private:
        LevelEventQueue eventQueue;
        std::vector unsigned int levelTimeCount;
        Window *mainWindow;
    };




// ---------- Status View




class StatusView : public View
    {
    public:
        StatusView( const Rect& r );
        ~StatusView()  { }
        void Paint( const Rect& updateRect );
        void HandleMessage( Message* pcMessage );
    private:
        StringView *scoreStringView;
        int32 score;
        float health;
    };




// ---------- Game View




class GameView : public View
    {
    public:
        GameView( const Rect& r ); /* Constructor */
        ~GameView();
        void AttachedToWindow();
        void Paint( const Rect& updateRect );
        void KeyUp( const char *pzString, const char *pzRawString, uint32 nQualifiers );
        void KeyDown( const char *pzString, const char *pzRawString, uint32 nQualifiers );
        void GameHeartbeat( void );
        void setLevel( String level );
        void fireEnemyBullet( Point location, unsigned int type );
    private:
        Star stars[NUM_STARS];
        Color32_s star_color[3];
        EnemyManager enemyManager;
        Player player;
        View* drawingView;
        Bitmap* offscreenBitmap;
        Bitmap* onscreenBitmap;
        bool holdingUpArrow;
        bool holdingDownArrow;
        bool holdingLeftArrow;
        bool holdingRightArrow;
        unsigned int holdingFireButton;
        unsigned int rechargeDelay;
        MediaManager *pcManager;
        MediaSoundPlayer *bulletSound, *backgroundMusic;
    };




// ---------- Game Window




class GameWindow : public Window
    {
    public:
        GameWindow( const Rect& r ); /* Constructor */
        void HandleMessage( Message* pcMessage );
        bool OkToQuit();
        status_t loadLevelSet( String level_set );
        std::vector<tring>levels;
    private:
        GameView *gameView;
        StatusView *statusView;
        HeartbeatThread *thread;
        unsigned int currentLevel;
        friend class TestApplication;
    };




#endif