//
//  Screens.h
//  MetarealEngine
//
//  Created by David Van Brink on 12/24/14.
//  Copyright (c) 2014 David Van Brink. All rights reserved.
//

#ifndef __MetarealEngine__Screens__
#define __MetarealEngine__Screens__

#include <vector>

#include "Me.h"
#include "MeHelpers.h" // for all to enjoy

class Screen;

/// manage a collection of screens, including fading from one to the next, &c
class Screens
{
public:
    Screens(int width, int height, const char *baseDir);
    virtual void begin();
    virtual void setSize(int width, int height);
    virtual void keyDown(int k, int mod);
    virtual void keyUp(int k);
    virtual void mouseDown(int x, int y);
    virtual void mouseUp(int x, int y);
    virtual void tick();
    virtual void draw(MeIFrameBuffer *destinationBuffer = 0, int renderSequence = -1);
    virtual void end();
    
private:
    int tickCount = 0;
    MeIMaterial *faderMaterial;
    MeIFrameBuffer *windowFrameBuffer;
    MeIFrameBuffer *fadeInFrameBuffer;
        
    MeRenderWorld *faderWorld;
    std::vector<Screen *> screens;
    
    int currentScreen;
    int previousScreen;
    int framesSinceChange;
    
    void captureFrame();
    
    MeIMaterial *m = NULL;
    MeIFrameBuffer *captureBuffer = NULL;

};

class TerminalHam;

/// describes a single screen
class Screen
{
public:
    Screen();
    virtual void begin();
    virtual void setSize(int width, int height);
    virtual void keyDown(int k);
    virtual void keyUp(int k);
    virtual void partClicked(int partId);
    virtual void tick();
    virtual void draw(MeIFrameBuffer *destination, int renderSequenceNumber = -1);
    virtual void end();
    
    bool keyTook;
    
    virtual std::string getName() = 0;
    
protected:
    MeRenderWorld *renderWorld = NULL;
    bool pipelineEnabled = true;
    int renderSequence = 0; // draw(dest, -1) means use this one.

    MeIMaterial *handyMaterial;
    MeIMaterial *materialSky;
    MeVec4 cameraMoving;
    MeVec4 cameraTurning;
    
    MeVec4 cameraMovingP;
    MeVec4 cameraTurningP;
    
    MeMatrix4 cameraMatrix; // matrix affects the placement of the camera; inverse moves the world.
    
    float eyePos = 2.5;
    float eyePosChange = 0;
    
    float v = 0.23; // velocity
    float vD = v / 44;
    float t = 0.017; // turning
    float tD = t / 44;
    
    float time = 0.0;
    int ticks = 0;

    
    void makeSkybox();
    TerminalHam *th;

    
#define buffer0Dim 64
    MeIFrameBuffer *buffer0;
};

class ITickableThing : public MeThing
{
public:
    virtual void setMaterial(MeIMaterial *material) = 0;
    virtual MeGaud *getGaud() = 0;
    virtual void tick() = 0;

};



// utilities



void xaddCopyingStep(MeRenderWorld *rw, std::string sourceFrameBuffer, std::string destFrameBuffer, const char *fsh = "texture2d.fsh", bool doDepth = false);

#endif /* defined(__MetarealEngine__Screens__) */
