#version 330 core

// mods on 8mar18...
// added lRad (leg length) + vertical adjustment
// changed swim arm stroke

layout(location = 0) in vec3 modelPos;
layout(location = 1) in vec2 modelUV;

out float opacity;
out vec2 UV;

// MVP must match string in glGetUniformLocation(pid,"MVP")
uniform mat4 MVP;
uniform float mytime;
uniform vec3 wPos;
uniform float horiAng;

uniform int direction; 
//-1=>back, 0=>stop, 1=>forward, 2=>swim, 3=>tread, 4=>push
// 5=>rightShoot, 6=leftShoot

uniform int fade; // 0=>normal, 1=>reducedOpacity
uniform int inside; // 0=>beach, 1=>interior


const vec3 hRad = vec3(0.02,0.02,0.01); // head dimensions
const vec3 bRad = vec3(0.02,0.03,0.012); // body dimensions
const vec3 aRad = vec3(0.01,0.03,0.01); // arm dimensions
const vec3 lRad = vec3(0.01,0.03,0.01); // leg dimensions

const float fOffz = 0.60; //0.40; // magnitude of stride

// define a ftn giving zoffsets to feet
float walkingDZ( float tm, int dir ) {
	float x;
	if( dir>0 ) x=tm;
	else x=-tm;
	float dz = fOffz*sin(x);
	if ((dir==0)||(dir>=4)) dz=0.0; //either stopped, pushing, or shooting
	//if ((dir==0)||(dir==4)) dz=0.0; //either stopped or pushing
	return dz;
} // end walkingDZ


const float onepi = 3.14159;

// avatar is defined as a unit radius cube centered on origin
// made up of 6 rectangular parts (colored, not textured):
// Y>0.5 is head
// Y>0.0 is torso
//
// ---------------- bottom layer has 4 parts:
//
// leg leg    ^
// arm arm    |
//            Z
//      <---X
//





void main(){

	vec3 posrot;
	int id;
	float dz;

	float angl = horiAng;
	vec3 pos = modelPos;

// First, we identify body segment

	if (pos.y > 0.5)      id=0; //head
	else if (pos.y > 0.0) id=1; //torso

	else if (pos.z>0.0) //legs
	{
		if (pos.x>0.0) id=2; //left leg
		else           id=3; //right leg
	}

	else  //arms pos.z<0
	{
		if (pos.x>0.0) id=4; //left arm
		else           id=5; //right arm
	}
	



	if (id==0) {             //head

		pos.y -= 0.75; // Xlate to origin

		pos.x *= hRad.x;
		pos.y *= 4.0*hRad.y;
		pos.z *= hRad.z;
		// now is expanded to proper size

		pos.y += hRad.y+2.0*bRad.y; // Xlate up into position

	}

	else if (id==1) {             //torso

		pos.y -= 0.25; // Xlate to origin

		pos.x *= bRad.x;
		pos.y *= 4.0*bRad.y;
		pos.z *= bRad.z;
		// now is expanded to proper size

		pos.y += bRad.y; // Xlate up

	}

	else if (id==3) {            //right leg

		pos.x+=0.5;  pos.y+=0.5; pos.z-=0.5; // Xlate to origin

		pos.x *= 2.0*lRad.x;
		pos.y *= 2.0*lRad.y;
		pos.z *= 2.0*lRad.z;
		// now is expanded to proper size

		pos.x -= lRad.x; // move outboard
		pos.y -= lRad.y; // Xlate down

		pos.x -= 0.002; // move outboard slightly

	}
	else if (id==2) {            // left leg

		pos.x-=0.5;  pos.y+=0.5; pos.z-=0.5; // Xlate to origin

		pos.x *= 2.0*lRad.x;
		pos.y *= 2.0*lRad.y;
		pos.z *= 2.0*lRad.z;
		// now is expanded to proper size

		pos.x += lRad.x; // move outboard
		pos.y -= lRad.y; // Xlate down

		pos.x += 0.002; // move outboard slightly

	}

	else if (id==5) {            //right arm

		pos.x+=0.5;  pos.y+=0.5; pos.z+=0.5; // Xlate to origin

		pos.x *= 2.0*aRad.x;
		pos.y *= 2.0*aRad.y;
		pos.z *= 2.0*aRad.z;
		// now is expanded to proper size

		pos.x -= aRad.x+bRad.x; // Xlate rightward
		pos.y -= aRad.y; // Xlate down

	}
	else if (id==4) {            // left arm

		pos.x-=0.5;  pos.y+=0.5; pos.z+=0.5; // Xlate to origin

		pos.x *= 2.0*aRad.x;
		pos.y *= 2.0*aRad.y;
		pos.z *= 2.0*aRad.z;
		// now is expanded to proper size

		pos.x += aRad.x+bRad.x; // Xlate leftward
		pos.y -= aRad.y; // Xlate down

	}




float freq=10.0; //15.0;
float ampleg=1.2; //1.0;
float amparm=1.2; //1.0;
if (direction>1) // swimming or treadwater
{
	freq=8.7;
	if(direction==2) { //swim
		ampleg=2.0;
		amparm=2.0;
	}
	else {  // dir==3 => tread
		ampleg=1.0; //1.5;
		amparm=2.0;
	}
}


// legs need to walk here, BEFORE rotation...
// move fore/aft with sine motion, 
// proportional to distance from top @ y=zero
	if ( (id==3 ) ) { //rightleg
		pos.z += pos.y *ampleg* walkingDZ(freq*mytime,direction);
	} else if ( (id==2) ) { //leftleg
		pos.z += pos.y *ampleg* walkingDZ(freq*mytime+onepi,direction);
	}


if( direction==6 ) { // leftShoot

	// set hands wider than shoulders
	if( id==5 ) //rightarm
		pos.x += 0.1*pos.y;

	if (  (id==5) ) //move arms upward
		pos.y += 2.0*bRad.y;   //shoulders to torso top


	if(id==4)  { //rotate left arm 90 deg forward
		float oy=pos.y;
		float oz=pos.z;
		float tr=onepi/2.0; // 90deg
		pos.z=cos(tr)*oz-sin(tr)*oy;
		pos.y=sin(tr)*oz+cos(tr)*oy;

		pos.y += 2.0*bRad.y;
	}

}
else if( direction==5 ) { // rightShoot

	// set hands wider than shoulders
	if( id==4 ) //leftarm
		pos.x -= 0.1*pos.y;

	if ( (id==4)  ) //move arms upward
		pos.y += 2.0*bRad.y;   //shoulders to torso top


	if(id==5)  { //rotate right arm 90 deg forward
		float oy=pos.y;
		float oz=pos.z;
		float tr=onepi/2.0; // 90deg
		pos.z=cos(tr)*oz-sin(tr)*oy;
		pos.y=sin(tr)*oz+cos(tr)*oy;

		pos.y += 2.0*bRad.y;
	}

}
else if( direction==4 ) { // pushing

	if( (id==4) || (id==5) ) { //rotate arms 90 deg forward
		float oy=pos.y;
		float oz=pos.z;
		float tr=onepi/2.0; // 90deg
		pos.z=cos(tr)*oz-sin(tr)*oy;
		pos.y=sin(tr)*oz+cos(tr)*oy;

		pos.y += 2.0*bRad.y;
	}

}
else if( direction<2 ) { // walking or stopped

	// arms need to swing here, BEFORE rotation
	if ( (id==4) ) { // leftarm
		pos.z += 0.5*pos.y *amparm* walkingDZ(freq*mytime,direction);
	} else if ( (id==5) ) { // rightarm
		pos.z += 0.5*pos.y *amparm* walkingDZ(freq*mytime+onepi,direction);
	}

	// set hands wider than shoulders
	if( id==4 ) //leftarm
		pos.x -= 0.1*pos.y;
	else if( id==5 ) //rightarm
		pos.x += 0.1*pos.y;

	if ( (id==4) || (id==5) ) //move arms upward
		pos.y += 2.0*bRad.y;   //shoulders to torso top
}

else // dir=3 (treadwater or dir=2 (swim)
{

	if( direction==3 ) { // treadwater

		//move arms sideways like treading water or breast-stroke:
		if ( (id==4) ) { // leftarm
			pos.x += 0.3*pos.y *amparm* (-fOffz+walkingDZ(freq*mytime,direction));
		} else if ( (id==5) ) { // rightarm
			pos.x += 0.3*pos.y *amparm* (fOffz+walkingDZ(freq*mytime+onepi,direction));
		}

	} else if( direction==2 ) { //swim

		if(id==4) {
			pos.z += 0.5*pos.y *amparm* walkingDZ(freq*mytime,direction);
			pos.x += 0.3*pos.y *amparm* (-fOffz+walkingDZ(freq*mytime+onepi,direction));
		} else if(id==5) {
			pos.z += 0.5*pos.y *amparm* walkingDZ(freq*mytime+onepi,direction);
			pos.x += 0.3*pos.y *amparm* (fOffz+walkingDZ(freq*mytime+onepi,direction));
		}

	}

	if( (id==4) || (id==5) ) { //rotate arms 90 deg forward

		if( direction==3 ) { //treadwater

			float oy=pos.y;
			float oz=pos.z;
			float tr=onepi/2.0; // rotate arms 90deg forward
			pos.z=cos(tr)*oz-sin(tr)*oy;
			pos.y=sin(tr)*oz+cos(tr)*oy;

			pos.y += 2.0*bRad.y;

		}
		else if( direction==2 ) { //swim

			float oy=pos.y;
			float oz=pos.z;
			//float tr=onepi*0.75; // rotate arms 135deg forward
			float tr=onepi*0.66; // rotate arms 120deg forward
			pos.z=cos(tr)*oz-sin(tr)*oy;
			pos.y=sin(tr)*oz+cos(tr)*oy;

			pos.y += 2.0*bRad.y;

		}

	}

	// tilt rest of body 30 deg forward
	if( direction==2 )
	{

		float a=-onepi/3.0; 
		//tilt 60 deg forward
		float oy=pos.y;
		float oz=pos.z;
		pos.y = +cos(a)*oy + sin(a)*oz;
		pos.z = -sin(a)*oy + cos(a)*oz;

	}

} // end if


	if( direction==3 ) { //treadwater
		pos.y -= 0.03; // move lower
	}



	// rotate per attitude
	posrot.y = pos.y;
	posrot.x = +cos(angl)*pos.x + sin(angl)*pos.z;
	posrot.z = -sin(angl)*pos.x + cos(angl)*pos.z;
	// now is rotated to proper look-direction

	if( inside>0 ) 
		posrot *= 3.0; // enlarge avatar in dungeon
	
	//else posrot *= 0.9; // shrink on beach


	// translate into position
	posrot += wPos;


	// adjust to put feet on ground
	if( inside<1 ) posrot.y -= 0.17; //8mar18 adjustment 0.18; //on beach
	else posrot.y -= 0.45; //8mar18 adjustment 0.5; //in dungeon



	if( fade>0 ) opacity = 0.3; //show hand for DHD
	else opacity=1.0;

	gl_Position =  MVP * vec4(posrot,1.0);

	UV = modelUV;

}


//--
//-- Copyright (C) 2020  <fastrgv@gmail.com>
//--
//-- This program is free software: you can redistribute it and/or modify
//-- it under the terms of the GNU General Public License as published by
//-- the Free Software Foundation, either version 3 of the License, or
//-- (at your option) any later version.
//--
//-- This program is distributed in the hope that it will be useful,
//-- but WITHOUT ANY WARRANTY; without even the implied warranty of
//-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//-- GNU General Public License for more details.
//--
//-- You may read the full text of the GNU General Public License
//-- at <http://www.gnu.org/licenses/>.
//--


