#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
	
	ofSetVerticalSync(true);
	ofSetFrameRate(30);
	
	ofxiPhoneGetOrientation();
	ofRegisterTouchEvents(this);
	ofxiPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);
	ofBackground(13,152,214);

	
	// add the newFloat method to listen for eventsAddon newFloatEvent
	ofAddListener(evObject.newFloatEvent,this,&testApp::newFloat);
	
	// add the newFloat method to listen for eventsAddon newFloatEvent
	ofAddListener(evObject.newIntEvent,this,&testApp::newInt);
	
	
	// initialize the accelerometer
	ofxAccelerometer.setup();

	
	VF.setupField(60,40,ofGetWidth(), ofGetHeight());
	
	//treasure
	////////IMAGE NEEDS TO CHANGE////
	treasureImage.loadImage("images/treasure.png");
	
	//background images
	winBack.loadImage("images/win.png");
	loseBack.loadImage("images/lose.png");
	background.loadImage("images/background.gif");

	

		
	boatImage.loadImage("images/treasure.png");

	//ofSetCircleResolution();
	ofSetRectMode(OF_RECTMODE_CENTER);

	
	//boat
	pictureB.loadImage("images/boatK.png");
	
	//sharks
	sharkImage.loadImage("images/sharks.png");

	
	//springs
	
	picture2.loadImage("images/seaweed.png");
	
	printf(" width %d \n",ofGetWidth());
	printf("height %d \n",ofGetHeight());

	
	//whirlpool
	pictureW.loadImage("images/whirlpools.png");


	//////////VECTORFIELD
	VF.setupField(60,80,ofGetWidth(), ofGetHeight());
	lastTime=0;
	start= ofGetElapsedTimef();
	restart();

}

//--------------------------------------------------------------
void testApp::update(){
	
//	VF.fadeField(0.99);
	
	currentAccelData.x = (ofxAccelerometer.getForce().y - InitAccelData.y)*10;

	if (InitAccelData.x<=0) {
		currentAccelData.y = (ofxAccelerometer.getForce().x - InitAccelData.x)*10;

	} else if (InitAccelData.x>0) {
		currentAccelData.y = (ofxAccelerometer.getForce().x + InitAccelData.x)*10;

	} 
	///////NOISE F
	//NF.setTime(ofGetElapsedTimef()*0.01);
	//NF.scaleOfField = ofMap(3000, 0,ofGetWidth(),0,1);
	///////////////


	//SHARKS
	
	for (int i = 0; i < sharks.size(); i++){
		float smooth=0.5;
		sharks[i].cohesion.distance = 54.4*smooth;
		sharks[i].alignment.distance = 16.7*smooth;;
		sharks[i].seperation.distance = 50.3*smooth;;
		sharks[i].cohesion.strength = 0.1*smooth;;
		sharks[i].alignment.strength = 0.25*smooth;;
		sharks[i].seperation.strength = 0.23*smooth;;
		sharks[i].damping = 0.015f;
	}
	
	
	for (int i = 0; i < sharks.size(); i++){
		sharks[i].resetForce();
	}
	
	for (int i = 0; i < sharks.size(); i++){
		for (int j = 0; j < sharks.size(); j++){
			if (i != j){
				sharks[i].addForFlocking(sharks[j]);	
			}
		}
		// this was something we tried in class (partitcle move away from mouse...)
		sharks[i].addAttractionForce(boat[0].pos.x, boat[0].pos.y, 1000, 0.1);
		
		//check colision
		
		if (sharks[i].calDist(boat[0])) {
			cout<<"sum of radius" << sharks[i].radiusSum;
			bHit=TRUE;
		}
	}

	for (int i=0; i<particles2.size(); i++) {
		if (particles2[i]->calDist(boat[0])) {
		bHit=TRUE;
		}
	}
	
	////////winning
	for (int i=0; i<treasure.size(); i++) {
		if (treasure[i].calDist(boat[0])) {
			bWin=true;
		}
	}	
	
	for (int i = 0; i < sharks.size(); i++){
		sharks[i].addFlockingForce();
		sharks[i].addDampingForce();
		sharks[i].bounceOffWallsSharks();
		sharks[i].update();
	}
	
	for (int i = 0; i < boat.size(); i++){
		boat[i].pos.x = boat[i].pos.x - currentAccelData.x;
		boat[i].pos.y = boat[i].pos.y  - currentAccelData.y;
		//sine movement
		boat[i].pos.y=boat[i].pos.y+cos(ofGetElapsedTimef()*4) ;		
		boat[i].bounceOffWalls();
		boat[i].addDampingForce();
        boat[i].update();
	}
	
	
	//springs
	for (int i = 0; i < springs.size(); i++){
		springs[i].distance = 5+ 5 * sin(ofGetElapsedTimef()+PI);
	}
	
	
	for (int i = 0; i < particles2.size(); i++){
		particles2[i]->resetForce();
	}
	
	for (int i = 0; i < particles2.size(); i++){
		
		for (int j = 0; j < i; j++){
			particles2[i]->addRepulsionForce(*particles2[j], 50, 0.1);
		}
	}
	
	for (int i = 0; i < springs.size(); i++){
		springs[i].update();
	}
	for (int i = 0; i < particles2.size(); i++){
		particles2[i]->bounceOffWalls();
		particles2[i]->addDampingForce();
		particles2[i]->update();
	}
	
	
	
	//whirlpool
	
	
	for (int i = 0; i < particlesW.size(); i++){
		particlesW[i]->resetForce();
		particles2W[i]->resetForce();
		
	}
	
	for (int i = 0; i < particlesW.size(); i++){
		
		
		particlesW[i]->addAttractionForce(ofRandom(ofGetWidth()/2+150,ofGetWidth()/2+160), ofRandom(ofGetHeight()/2-20,ofGetHeight()/2+10), 1000, 0.6f);
		particles2W[i]->addAttractionForce(150, 220, 1000, 0.6f);
		
		for (int j = 0; j < i; j++){
			particlesW[i]->addCounterClockwiseForce(*particlesW[j], 100, 0.09);
			particles2W[i]->addCounterClockwiseForce(*particles2W[j], 100, 0.09);
			
		}
	}
	
	for (int i = 0; i < particlesW.size(); i++){
		particlesW[i]->addDampingForce();
		particles2W[i]->addDampingForce();
		particlesW[i]->update();
		particles2W[i]->update();
		
	}
	
	//to ADD VF FORCE///////////////////
		for (int i = 0; i < boat.size(); i++){
		ofxVec2f frc;
		frc = VF.getForceFromPos(boat[i].pos.x, boat[i].pos.y);
		boat[i].addForce(frc.x, frc.y);
		}
	
}

//--------------------------------------------------------------
void testApp::draw(){

	ofEnableAlphaBlending();
	//VF.draw();
	// then draw:		
	//MESSAGE
	//sec= ofGetElapsedTimef() - start;
	sec = 30-ofGetElapsedTimef()+lastTime;
	
	//ofDrawBitmapString("You have", 100, 20);
	if(sec<=0 )
	{	//ofBackground(0, 0, 0);
		killParticles();
		loseBack.draw(ofGetWidth()/2, ofGetHeight()/2,ofGetWidth(),ofGetHeight());
		//ofDrawBitmapString("GAME OVER", ofGetWidth()/2-100, ofGetHeight()/2);
		//ofDrawBitmapString("YOU KILLED THE CHICKEN PIRATE", ofGetWidth()/2-100, ofGetHeight()/2+30);
	
	}
	else if(bHit){
		killParticles();
		sec=sec+(30-sec);
		loseBack.draw(ofGetWidth()/2, ofGetHeight()/2,ofGetWidth(),ofGetHeight());
		//ofDrawBitmapString("GAME OVER", ofGetWidth()/2-100, ofGetHeight()/2);
		bHit=true;
		
	}
	else if(bWin){
		killParticles();
		winBack.draw(ofGetWidth()/2, ofGetHeight()/2,ofGetWidth(),ofGetHeight());
		//ofDrawBitmapString("YOU WON", ofGetWidth()/2-100, ofGetHeight()/2);
		//ofDrawBitmapString("NEXT LEVEL", ofGetWidth()/2-100, ofGetHeight()/2+30);
	}
	
	if((!bWin) && (!bHit) && (sec>0)) {
				
		
		ofSetColor(255, 255, 255,30);
		background.draw(ofGetWidth()/2, ofGetHeight()/2,ofGetWidth(),ofGetHeight());

		ofSetColor(255, 255, 255);
		ofDrawBitmapString("You have ", 20, 20);
		ofSetColor(255, 0, 0);
		ofDrawBitmapString( ofToString(sec), 100, 20);
		ofSetColor(255, 255, 255,255);
		ofSetColor(255, 255, 255);
		ofDrawBitmapString("seconds", 130, 20);
		
		 //SHARKS

		for (int i = 0; i < sharks.size(); i++){
			//vector field stuff
			//VF.addClockwiseCircle(particles[i].pos.x, particles[i].pos.y, 100, 0.01f);
			sharks[i].draw2(&sharkImage);
		}
		
		//BOAT	
		for (int i = 0; i < boat.size(); i++){
			boat[i].drawBoat(&pictureB);
		}
		
		//springs
		for (int i = 0; i < particles2.size(); i++){
			particles2[i]->draw3(&picture2);
		}
		for (int i = 0; i < springs.size(); i++){
			springs[i].draw();
		}
		
		//whirlpool		
		ofSetColor(255, 255, 255,20);
		for (int i = 0; i < particlesW.size(); i++){
			particlesW[i]->draw4(&pictureW);
			particles2W[i]->draw4(&pictureW);			
		}
		ofSetColor(255, 255, 255,255);

		
		//TREASURE	
		for (int i = 0; i < treasure.size(); i++){
			treasure[i].drawBoat(&treasureImage);
		}
		
	}
	ofDisableAlphaBlending();
	

}

//--------------------------------------------------------------
void testApp::newFloat(float & f){

}
//--------------------------------------------------------------
void testApp::newInt(int & i){
}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){


}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){

}
//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){

	
	InitAccelData.x = ofxAccelerometer.getForce().x;
	InitAccelData.y = ofxAccelerometer.getForce().y;
	
	
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
	
	
	//start=ofGetElapsedTimef();       
	restart();

}
//-----------------------
void testApp::killParticles(){
	sharks.erase(sharks.begin(),sharks.end());
	particlesW.erase(particlesW.begin(),particlesW.end());
	particles2W.erase(particles2W.begin(),particles2W.end());
	springs.erase(springs.begin(),springs.end());
	boat.erase(boat.begin(),boat.end());
	treasure.erase(treasure.begin(),treasure.end());
	particles2.erase(particles2.begin(),particles2.end());
	bHit=FALSE;
	sec=0;
	
}


//------------------

void testApp::restart(){
	
	VF.clear();
	bWin=FALSE;
	bHit=FALSE;
	// register touch events
	w=ofGetWidth();//480
	h=ofGetHeight();//320
	w2=ofGetWidth()/2;//240
	h2=ofGetHeight()/2;//160
	
	//treasure
	for (int i = 0; i < 1; i++){
		particle myParticle;
		myParticle.setInitialCondition(ofGetWidth()-30, int(ofRandom(0, ofGetHeight())),40,40);
		treasure.push_back(myParticle);
	}
	
	//boats
	for (int i = 0; i < 1; i++){
		particle myParticle;
		myParticle.setInitialCondition(0, int(ofRandom(0, ofGetHeight())),0,0);
		boat.push_back(myParticle);
	}
	
	//sharks
	for (int i = 0; i < 3; i++){
		particle myParticle;
		myParticle.setInitialCondition(ofRandom(1000,1024),ofRandom(0,20),ofRandom(-1,-3),5);
		sharks.push_back(myParticle);
	}
	
	//springs
	
	
	
	for (int i = 0; i < 10; i++){
		particle * p = new particle();
		
		float x = 200 + 100 * cos ( (i / 200.0) * TWO_PI);
		float y = 130 + 100 * sin ( (i / 200.0) * TWO_PI);
		
		p->setInitialCondition(x,y ,0,0);
		particles2.push_back(p);
	}
	for (int i = 0; i < 10; i++){
		particle * p2 = new particle();
		
		float x = 20 + 80 * cos ( (i / 200.0) * TWO_PI);
		float y = 50 + 50 * sin ( (i / 200.0) * TWO_PI);
		
		p2->setInitialCondition(x,y ,0,0);
		particles2.push_back(p2);
	}
	
	
	
	// change this to
	// for (int i = 0; i < 10; i++){
	// to see a chain
	
	for (int i = 0; i < particles2.size()-1; i++){
		if(i==9)
		{
			i++;
		}
		spring mySpring;
		mySpring.distance		= 1;
		mySpring.springiness	= 0.5f;
		mySpring.particleA = ((particles2[i]));
		mySpring.particleB =  (particles2[(i+1) % particles2.size()]);
		springs.push_back(mySpring);
	}
	
	
	//WHIRLPOOL
	
	float xorig2=w2;
	float yorig2=h2;
	float xorig=ofGetWidth()/2;
	float yorig=ofGetHeight()/2;
	float rad=0.4;
	float rad2=0.6;
	
	for (int i = 0; i < 100; i++){
		
		float angle=ofGetElapsedTimef()*(1+i/100.0);
		float m=xorig+rad*cos(angle)*6;
		float n=yorig+rad*sin(angle)*2;
		float m2=xorig2+rad2*cos(angle)*6;
		float n2=yorig2+rad2*sin(angle)*2;
		float vx=m*0.3;
		float vy=n*0.3;
		float vx2=m2*0.4;
		float vy2=n2*0.4;
		
		
		
		
		particle * p= new particle();
		particle * p2 = new particle();
		
		p->setInitialCondition(m+150,n+10,ofRandom(0,vy),ofRandom(vx,0));
		p2->setInitialCondition(m2+10,n2-20,ofRandom(0,vy2),ofRandom(vx2,0));
		p->damping=(ofRandom(0.9,0.6));
		p2->damping=(ofRandom(0.9,0.6));
		
		
		particles2W.push_back(p2);
		particlesW.push_back(p);
		
	}
	
	
	int x=200;
	int y=170;
	
	//VF.addClockwiseCircle(x,y+20,10, 0.1f);
	//VF.addInwardCircle(x, y+20, 70, 0.5f);
	//VF.addOutwardCircle(x, y+20, 100, 0.9f);
	
	
	VF.addClockwiseCircle(x,y+20, 90, 0.6f);
	VF.addInwardCircle(x, y+20, 110, 0.6f);
	
	
	int x2=w2+200;
	int y2=h2;
	VF.addClockwiseCircle(x2,y2+20, 90, 0.6f);
	VF.addInwardCircle(x2, y2+20, 110, 0.6f);
	
	lastTime=ofGetElapsedTimef();
	
}





