#include "grafParticleVecField.h"

#define FLUID_WIDTH			150

grafParticleVecField::grafParticleVecField()
{
    alpha   = 1;
    mode    = 2;
    particle_damping = .25f;
    particle_size = 6.f;
    particle_alpha = .75f;


}

grafParticleVecField::~grafParticleVecField()
{
    //dtor
}

void grafParticleVecField::reset()
{

    // set up original set with lines
    PS.reset(WIDTH_FIELD,HEIGHT_FIELD);

    // set up extras for flare
    for( int i = 0; i < XTRA_PS.size(); i++)
        XTRA_PS[i].reset(WIDTH_FIELD,HEIGHT_FIELD);

    // set vector field
    VF.bReset = true;
    VF.clearField();

    // reset vars
    alpha=1;
    transitionCounter = 0;

}

void grafParticleVecField::setup(int w_, int h_)
{

    w = w_;
    h = h_;

	PS.setup(FIELD_SIZE,WIDTH_FIELD,HEIGHT_FIELD,w,h,&VF);

	particleSystem psx;
	int toatlXtra = 1;
	for( int i = 0; i < toatlXtra; i++)
	{
        XTRA_PS.push_back(psx);
        XTRA_PS[i].setup(FIELD_SIZE,WIDTH_FIELD,HEIGHT_FIELD,w,h,&VF);

	}

	setDamping( particle_damping);
	setParticleSize( particle_size );


}

void grafParticleVecField::setDamping( float val )
{

    particle_damping = val;
    PS.setParticleDropOffRate(particle_damping);

    for( int i = 0; i < XTRA_PS.size(); i++) XTRA_PS[i].dropOffRate = (.8*particle_damping) - (i*.01f );
    //setParticleDropOffRate( (.8*particle_damping) - (i*.01f ));

}
void grafParticleVecField::setParticleSize( float val )
{

    particle_size = val;
    PS.setParticleSize(particle_size);

    for( int i = 0; i < XTRA_PS.size(); i++) XTRA_PS[i].setParticleSize(particle_size*.75f);

}

void grafParticleVecField::update( grafTag * PR, ofPoint pointForTime, ofPoint vel, float dt, bool bUpdateVF)
{



    float zdepth = PR->getCurentZDepth();

    PS.update(dt*100,w,h,zdepth, alpha*particle_alpha, PR->bReset);

    for( int i = 0; i < XTRA_PS.size(); i++)
     XTRA_PS[i].update(dt*100,w,h,zdepth, alpha);

    VF.fadeField(0.98f);

	if(!PR->bReset)
		VF.update( pointForTime, vel, w, w, h);


}

void grafParticleVecField::retractParticles(float dt, float cx,  float cy)
{

    switch( mode )
    {
        case 0:
            transitionUpAndDown(dt,&PS);
            //for( int i = 0; i < XTRA_PS.size(); i++)  transitionUpAndDown(dt,&XTRA_PS[i]);
            break;
        case 1:
            transitionUp(dt,&PS);
            //for( int i = 0; i < XTRA_PS.size(); i++)  transitionUp(dt,&XTRA_PS[i]);
            break;
        case 2:
            transitionDown(dt,&PS);
            //for( int i = 0; i < XTRA_PS.size(); i++)  transitionDown(dt,&XTRA_PS[i]);
            break;
        case 3:
            transitionFireWorks(dt,&PS);
            //for( int i = 0; i < XTRA_PS.size(); i++)  transitionFireWorks(dt,&XTRA_PS[i],cx,cy);
            break;

    }

    transitionCounter++;


}

void grafParticleVecField::transitionUp(float dt, particleSystem * pst)
{
    /*for( int j= 0; j< pst->PTS.size(); j++)
    {

        float dist = pst->PTS[j].getDist();
        pst->PTS[j].vy += (dt*2) * (.01*dist);
        pst->PTS[j].py -= pst->PTS[j].vy * (dt*100);
    }*/

}

void grafParticleVecField::transitionDown(float dt, particleSystem * pst)
{
    /*for( int j= 0; j< pst->PTS.size(); j++)
    {

        float dist = pst->PTS[j].getDist();
        pst->PTS[j].vy += (dt*2) * (200.2+(.01*dist));
        pst->PTS[j].py += pst->PTS[j].vy * (dt*100);
    }*/
}

void grafParticleVecField::transitionUpAndDown(float dt, particleSystem * pst)
{
    /*for( int j= 0; j< pst->PTS.size(); j++)
    {

        float dist = pst->PTS[j].getDist();
        pst->PTS[j].vy += (dt*2) * (.01*dist);

        if( pst->PTS[j].py < 768/2 ) pst->PTS[j].py -= pst->PTS[j].vy * (dt*100);
        else                         pst->PTS[j].py += pst->PTS[j].vy * (dt*100);
    }*/
}


void grafParticleVecField::transitionFireWorks(float dt, particleSystem * pst, float cx,  float cy)
{


    /*for( int j= 0; j< pst->PTS.size(); j++)
    {

        //cout << pst->PTS[j].counter << endl;

        if(pst->PTS[j].counter==0) continue;

        //cout << "fwrks" << endl;

        float dist = 5;//.25*pst->PTS[j].getDist();

        ofxVec2f vecC = ofPoint(pst->PTS[j].px,pst->PTS[j].py)-ofPoint(cx,cy);
        vecC = vecC.normalize();


       // if(transitionCounter == 0 )
        pst->PTS[j].vx += dist*vecC.x*(dt*100);
       // if(transitionCounter == 0 )
        pst->PTS[j].vy += dist*vecC.y*(dt*100);

        pst->PTS[j].px += pst->PTS[j].vx*(dt*100);
        pst->PTS[j].py += pst->PTS[j].vy*(dt*100);

        pst->PTS[j].py += (20*dt);
        //pst->PTS[j].py += 10*(100*dt)*(100*dt);

        pst->PTS[j].vx -= .9*pst->PTS[j].vx*(dt*100);
        pst->PTS[j].vy -= .9*pst->PTS[j].vy*(dt*100);

    }*/
}

void grafParticleVecField::draw( grafTag * PR, int screenW, int screenH )
{


    float zdepth = PR->getCurentZDepth();

    ofNoFill();

    glPushMatrix();

        glTranslatef(-screenW/2, -screenH/2, 0);
        for( int i = 0; i < XTRA_PS.size(); i++)
        {
            XTRA_PS[i].draw(zdepth, alpha*particle_alpha, particle_size*.75f, false );
        }

        PS.draw(  zdepth, alpha*particle_alpha, particle_size );


    glPopMatrix();



}


