var BirdieBird = (function () {
	//var closed_left_eye = 0.75;
	//var closed_right_eye = 0.8;
	var closed_left_eye = 0.9;
	var closed_right_eye = 0.9;
	var bend_back = 1.;

	function mix(a,b,x)
	{
		return a + (b-a)*x;
	};

	function length(p) {
		return p.length();
	};

	function dot(p,q) {
		return p.dot(q);
	};

	function min(p,q) {
		return Math.min(p,q);
	};

	function max(p,q) {
		return Math.max(p,q);
	};

	function clamp(v,min_v,max_v) {
		return min(max_v,max(min_v,v));
	}

	var avec = new THREE.Vector3();
	function sphere( p,  x0, y0, z0,  r)
	{
		return avec.set(x0,y0,z0).sub(p).length() - r;
	};

	function plane( p,  nx, ny, nz,  d)
	{
	    return avec.set(nx,ny,nx).dot(p)-d;
	};

	function bendBody(p)
	{
	    // offset position to compute distance from to give the effect of the object moving
	    var bending = bend_back*0.025;
	    //float bending = 0.015*sin(4.*iGlobalTime);
	    p.z = p.z - p.y*p.y*bending;
	    /*#ifdef EAT_MUSHROOMS
	    p.x = p.x - sin(p.y);
	    #endif
	    #ifdef DANCE_GROOVE
	    float o = p.y*p.y*bending*2.*sin(4.*iGlobalTime);
	    p.x += o;
	    p.y += abs(o);
	    #endif
	    #ifdef DANCE_FUNK
	    float o2 = p.y*p.y*bending*2.*sin(4.*iGlobalTime);
	    p.x += o2;
	    p.y -= abs(o2);
	    #endif*/
	};

	var neck = 0.48;
	function birdieBody( p)
	{
	    // Model the body as a cylinder with varying radius
	    var y = clamp(p.y,0.,1.);

	    var r;
		var neck = 0.48;
	    if (y<neck)
	    	r = mix(1.4,0.15,y/neck);
	    else
	    {
	        var t = 1. - (y-neck)/(1.-neck);
	        r = -.85*t*t*t*t + 1.;
	        r *= Math.sin(Math.acos(1.-t));
	    }
	    
	    var body = Math.sqrt(p.x*p.x+p.z*p.z) - r*0.1;
	    return Math.max(Math.max(p.y-1.,-p.y),body);
	}

	function birdieBeak1( p)
	{
	    var d_back = p.z - (-0.02);
	    var d_bottom = -(p.y - 0.57);
	    var d_left = sphere(p,-.15, 0.6, 0.02,.2);
	    var d_right = sphere(p,.15, 0.6, 0.02,.2);
	    
	    return max(max(d_left,d_right),max(d_bottom,d_back));
	}

	function birdieBeak2( p)
	{
	    var d_back = p.z - (-0.02);
	    var d_top = plane(p, 0.,1.,-.6, 0.6);
	    var d_left = sphere(p,-.115, 0.65, 0.06,.2);
	    var d_right = sphere(p,.115, 0.65, 0.06,.2);
	    
	    return Math.max(Math.max(d_left,d_right),Math.max(d_top,d_back));
	}

	function birdieBeak( p)
	{
	    var beak1 = birdieBeak1(p);
	    var beak2 = birdieBeak2(p);
	    
	    return Math.min(beak1,beak2);
	}


	var eye_p = new THREE.Vector3();
	var eye_p2 = new THREE.Vector3();
	var pupiloff = new THREE.Vector3( 0.04, 0.0, 0);
	function birdieEyePupil(p)
	{
		eye_p.copy(p);
	    eye_p.y -= 0.717;
	    eye_p.z += 0.048;
	    
	    return min(eye_p2.subVectors(p,pupiloff).length(),eye_p2.addVectors(p,pupiloff).length()) - .025; // distance to sphere
	}

	function birdieEyeWhite(body, p)
	{
	    var d_bottom = plane(p,0.,-1.,0.,-0.69);
	    var d_top = plane(p,0.,1.,0.,0.9);
	    var d_sphere = min(sphere(p,0.1,0.75,-0.1,.1),
	                         sphere(p,-0.1,0.75,-0.1,.1));
	    return max(max(body,d_sphere),max(d_top,d_bottom));
	}

	function birdieBandana(body, p)
	{
	    var d_bottom = plane(p,0.,-1.,0.,-0.85);
	    var d_top = plane(p,0.,1.,0.,0.91);
	    return Math.max(body,Math.max(d_top,d_bottom));
	}

	function birdieEyeLid( p,  closed_left,  closed_right)
	{
		eye_p.copy(p);
	    eye_p.y = (eye_p.y-0.75)*0.5 + 0.75;
	    var d_bottom = plane(eye_p,-.8*(1.-closed_left),-1.,0.,-0.9 + 0.21*closed_left);
	    var d_sphere1 = sphere(eye_p,-0.1,0.75,-0.1,.1);
	    var d_sphere2 = sphere(eye_p,0,0.77,0,.1);
	    var lid1 = Math.max(Math.max(d_sphere1,d_sphere2),d_bottom);

	    d_bottom = plane(eye_p,0.8*(1.-closed_right),-1.,0.,-0.9 + 0.21*closed_right);
	    d_sphere1 = sphere(eye_p,0.1,0.75,-0.1,.1);
	    d_sphere2 = sphere(eye_p,0,0.77,0,.1);
	    var lid2 = Math.max(Math.max(d_sphere1,d_sphere2),d_bottom);
	    return Math.min(lid1,lid2);
	}

	var scenedist_p = new THREE.Vector3();
	return {
	scenedist: function(p)
	{
		scenedist_p.copy(p);
	    //bendBody(scenedist_p);
	    var body = birdieBody(p);
	    var beak = birdieBeak(p);
	    var eyepupil = birdieEyePupil(p);
	    var eyewhite = birdieEyeWhite(body,p);
	    var eyelid = birdieEyeLid(p,closed_left_eye, closed_right_eye);
	    /*#ifdef BANDANA
	    var ninjabandana = birdieBandana(body,p);
	    #endif
	    
	    #ifdef ONLY_BEAK
	    body += 10.;
	    eyepupil += 10.;
	    eyewhite += 10.;
	    eyelid += 10.;
	    #endif*/

	    var m = min(min(min(body,beak),min(eyepupil,eyewhite)),eyelid);
	    
	    if (m==beak) return [0.8, 0.4, 0.2, m];
	    if (m==eyepupil) return [0.0, 0.0, 0.0, m];
	    //#ifdef BANDANA
	    //if (m==ninjabandana) return [0.1, 0.2, 0.3, m];
	    //#endif
	    if (m==eyewhite) return [1.0, 1.0, 1.0, m];
	    if (m==eyelid) return [0.6, 0.6, 0.6, m];
	    return [0.8, 0.8, 0.8, m]; // m==body
	}
	};
})();
