#include "cRainDrop.h"

#include <stdlib.h>

cRaindrop::cRaindrop(cParticleSystem* ps) : cParticle(ps) 
{ 
    //velocity_ = cVector(0, -50, 0);
    velocity_ = cVector(0, -25, 0);
}

void cRaindrop::update(float dt, vector<cTriangle*>& tlist)
{
    age_ += dt;
    if(age_ > 3) {dead_ = true; return; }
    
    cVector g(0, -25, 0);
    cVector endPosition = position_ + velocity_ * dt;
    
    
    float velocityMag = velocity_.length();
    cVector normalizedVelocity = velocity_ / velocityMag;
    cIntersectionResult closest(false, 1000000000.0);
    cVector normal;
    for(int i = 0; i < tlist.size(); ++i)
    {
        
        cIntersectionResult result = 
            intersectTriangle(position_, normalizedVelocity, velocityMag * dt, *tlist[i]);

        if(!result.intersected_) continue;
        
        if(result.beta_ < closest.beta_)
        {
            closest = result;
            normal = tlist[i]->getNormal();
        }
    }
    
    if(!closest.intersected_) // no intersection
    {
        position_ = endPosition;
        velocity_ += dt * g;
        return;
    }
    
    position_ += normalizedVelocity * closest.beta_;
    
    // bounce
    cVector reflectedVelocity = (velocity_ - 2 * (normal.dot(velocity_)) * normal) * .15;
    
    dead_ = true;
    
    for(int i = 0; i < 5; ++i)
    {
       float a = ((float)(rand()%100))/100.0f;
       float b = ((float)(rand()%100))/100.0f;
       float c = ((float)(rand()%100))/100.0f;
       
       cSplashParticle* p = ps_->addSplash();
       p->position_ = position_;
       p->velocity_ = .3 * reflectedVelocity + 10 * cVector(a-.5, b-.5, c-.5);
    }
}
    
void cRaindrop::draw()
{	
    float scale = .05;
    float yscale = 3;
    
    glColor4f(.4,.4,1, .5);
    
    glBegin(GL_TRIANGLE_STRIP);						// Build Quad From A Triangle Strip
        glTexCoord2d(1,1); glVertex3f(position_.x_+scale, position_.y_+yscale, position_.z_); // Top Right
        glTexCoord2d(0,1); glVertex3f(position_.x_-scale, position_.y_+yscale, position_.z_); // Top Left
        glTexCoord2d(1,0); glVertex3f(position_.x_+scale, position_.y_, position_.z_); // Bottom Right
        glTexCoord2d(0,0); glVertex3f(position_.x_-scale, position_.y_, position_.z_); // Bottom Left
    glEnd();
    
    glBegin(GL_TRIANGLE_STRIP);						// Build Quad From A Triangle Strip
        glTexCoord2d(1,1); glVertex3f(position_.x_, position_.y_+yscale, position_.z_+scale); // Top Right
        glTexCoord2d(0,1); glVertex3f(position_.x_, position_.y_+yscale, position_.z_-scale); // Top Left
        glTexCoord2d(1,0); glVertex3f(position_.x_, position_.y_, position_.z_+scale); // Bottom Right
        glTexCoord2d(0,0); glVertex3f(position_.x_, position_.y_, position_.z_-scale); // Bottom Left
    glEnd();
        
}

cIntersectionResult cRaindrop::intersectTriangle(cVector& start, cVector& dir, float maxDist, cTriangle &triangle)
{

    float u, v;
    cVector edge1, edge2, tvec, pvec, qvec;
    float det, invDet;
    
    edge1 = *triangle.v1_ - *triangle.v0_;
    edge2 = *triangle.v2_ - *triangle.v0_;
    pvec = dir.cross(edge2);
    
    det = edge1.dot(pvec);

   if(det > -.000001 && det < .000001)
        return cIntersectionResult(false, 1);
        
   invDet = 1/det;

   tvec = start - *triangle.v0_;

   u = tvec.dot(pvec) * invDet;
   if(u < 0 || u > 1)
        return cIntersectionResult(false, 1);

   qvec = tvec.cross(edge1);

   v = dir.dot( qvec) * invDet;
   if(v < 0 || (u + v) > 1)
        return cIntersectionResult(false, 1);

      
    float dist = edge2.dot(qvec) * invDet;
    if(dist < 0 || dist > maxDist)
        return cIntersectionResult(false, 1);
   
    return cIntersectionResult(true, dist); // we use intersection result's beta as distance, not beta
}