//
//  ScreenG1.cpp
//  MetarealEngine
//
//  Created by David Van Brink on 1/19/15.
//  Copyright (c) 2015 David Van Brink. All rights reserved.
//

#include "ScreenG1.h"


MePart *makeBoxPart(MeVec3 p1, MeVec3 p2, MeIMaterial *material, int color)
{
    MeGeometry *g = makeBoxGeometry(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], color);
    MePart *p = new MePart(material, g);
    return p;
}

MeGaud *makeBoxGaud(MeVec3 p1, MeVec3 p2, MeIMaterial *material, int color)
{
    MePart *p = makeBoxPart(p1, p2, material, color);
    MeGaud *g = new MeGaud();
    g->addPart(p);
    return g;
}




class FlyerHam : public MeHam
{
public:
    MeGaud *flyerG;
    MePart *flyer1;
    MePart *flyer2;
    MeIMaterial *material;
    
    MeMatrix4 flyer1M;
    MeMatrix4 flyer2M;
    bool flyer2Accellerate;
    
    float flyer2Speed = 0;
    float height = 0;
    float verticalVelocity = 0;

    FlyerHam(MeRenderWorld *rw, MeIMaterial *material)
    {
        this->material = material;
        this->flyer1 = makeBoxPart(MeVec3(-0.5, 0.0, -0.5), MeVec3(0.5, 1.5, 0.5), this->material, 0x802020);
        this->flyer2 = makeBoxPart(MeVec3(-2.5, 1.55, -0.1), MeVec3(2.5, 1.6, 0.1), this->material, 0x204070);
        this->flyerG = new MeGaud();
        this->flyerG->addPart(this->flyer1);
        this->flyerG->addPart(this->flyer2);
        rw->addGaud(this->flyerG);
        setGaudMatrix(this->flyerG);
    }
    
    void updateFrame()
    {
        float oldHeight = this->height;
        {
            float speedup = .001;
            float slowdown = speedup * .7;
            this->flyer2Speed += this->flyer2Accellerate ? speedup : -slowdown;
            if(this->flyer2Speed < 0)
                this->flyer2Speed = 0;
        }
        flyer2M.lRotateY(this->flyer2Speed);
        
        float lift = (this->flyer2Speed) - 0.1 - height / 12;
        lift /= 100;

        this->verticalVelocity += lift;
        height += this->verticalVelocity;
        if(height <= 0)
        {
            height = 0;
            verticalVelocity = fabs(verticalVelocity / 2.0);
        }
        
        if(height > 0)
        {
            float baseSpin = pinRangeF(this->flyer2Speed / 7,0,.0015);
            if(baseSpin > 0)
                this->flyer1M.lRotateY(baseSpin);
        }
        
        float heightChange = this->height - oldHeight;
        this->flyer1M.lTranslate(MeVec3(0,heightChange,0));
        this->flyer2M.lTranslate(MeVec3(0,heightChange,0));
        setPartMatrix(this->flyer2, this->flyer2M);
        setPartMatrix(this->flyer1, this->flyer1M);
    }
    
    void accellerate(bool on)
    {
        this->flyer2Accellerate = on;
    }
};

ScreenG1::ScreenG1() : Screen()
{
    this->material = loadMaterialGl("vert1_v4.vsh", "frag1_v4.fsh");
    this->renderWorld = new MeRenderWorld();
    this->world = new MeWorld();

    this->groundG = makeBoxGaud(MeVec3(-5,-.1,-5), MeVec3(5,0,5), this->material, 0x202060);
    this->renderWorld->addGaud(this->groundG);
    setGaudMatrix(this->groundG);
    
    {
        FlyerHam *fh = new FlyerHam(this->renderWorld, this->material);
        this->world->addHam(fh);
        this->flyerHam = fh;
    }
    
    this->makeSkybox();

    this->cameraMatrix.lTranslate(0, 3, 15);

    this->renderWorld->addStepClear("", 0x402020);
    this->renderWorld->addStepDraw(this->materialSky, "");
    this->renderWorld->addStepDraw(this->material, "");
}

void ScreenG1::begin()
{
    
}
void ScreenG1::keyDown(int k)
{
    switch(k)
    {
        case ' ':
            ((FlyerHam *)this->flyerHam)->accellerate(true);
            break;
        default:
            this->Screen::keyDown(k);
    }
}
void ScreenG1::keyUp(int k)
{
    switch(k)
    {
        case ' ':
            ((FlyerHam *)this->flyerHam)->accellerate(false);
            break;
        default:
            this->Screen::keyUp(k);
    }
}
void ScreenG1::tick()
{
    this->world->updateFrame();
    this->Screen::tick();
}
void ScreenG1::draw(MeIFrameBuffer *destination)
{
    this->renderWorld->draw(destination);
}
