uniform sampler2D tex0;
varying vec4 pos;
uniform vec4 ModelViewMatrixOfFrameColumn0;
uniform vec4 ModelViewMatrixOfFrameColumn1;
uniform vec4 ModelViewMatrixOfFrameColumn2;
uniform vec4 ModelViewMatrixOfFrameColumn3;
uniform vec4 vertex00;
uniform vec4 vertex01;
uniform vec4 vertex10;
uniform vec4 vertex11;
uniform vec4 viewport;

float  DistanceToPossibleIntersection(vec2 vertex, vec2 begin, vec2 end, vec2 other_line_begin, vec2 other_line_end)
{
    	vec2 intersection;  
	 float denom = ((other_line_end.y - other_line_begin.y)*(end.x - begin.x)) -
                      ((other_line_end.x - other_line_begin.x)*(end.y - begin.y));

        float nume_a = ((other_line_end.x - other_line_begin.x)*(begin.y - other_line_begin.y)) -
                       ((other_line_end.y - other_line_begin.y)*(begin.x - other_line_begin.x));

        float nume_b = ((end.x - begin.x)*(begin.y - other_line_begin.y)) -
                       ((end.y - begin.y)*(begin.x - other_line_begin.x));

		if (denom==0.0)
		{
			//return 10000.0; //parallel
		}

        float ua = nume_a / denom;
        float ub = nume_b / denom;

       // if ( /*ua >= 0.0 && ua <= 1.0 &&*/ ub >= 0.0 && ub <= 1.0)
		//{
            // Get the intersection point.
            intersection.x = begin.x + ua*(end.x - begin.x);
            intersection.y = begin.y + ua*(end.y - begin.y);
			
			return length(vertex-intersection);
		//}

	//return 10000.0;
}



float DistancePointLine( vec2 Point, vec2 LineStart, vec2 LineEnd )
{
    float LineMag;
    float U;
    vec2 Intersection;
 
    LineMag = length( LineEnd-LineStart );
 
    U = ( ( ( Point.x - LineStart.x ) * ( LineEnd.x - LineStart.x ) ) +
        ( ( Point.y - LineStart.y ) * ( LineEnd.y - LineStart.y ) )  ) /
        ( LineMag * LineMag );
 
   
    Intersection.x = LineStart.x + U * ( LineEnd.x - LineStart.x );
    Intersection.y = LineStart.y + U * ( LineEnd.y - LineStart.y );
    //Intersection.z = LineStart.z + U * ( LineEnd.z - LineStart.z );
 	
 	return length(Point-Intersection);
}

vec4 PointOnLineNearestToPoint( vec4 Point, vec4 LineStart, vec4 LineEnd )
{
    float LineMag;
    float U;
    vec4 Intersection;
 
    LineMag = length( LineEnd-LineStart );
 
    U = ( ( ( Point.x - LineStart.x ) * ( LineEnd.x - LineStart.x ) ) +
        ( ( Point.y - LineStart.y ) * ( LineEnd.y - LineStart.y ) ) +
        ( ( Point.z - LineStart.z ) * ( LineEnd.z - LineStart.z ) ) +
		( ( Point.z - LineStart.w ) * ( LineEnd.z - LineStart.w ) )) /
        ( LineMag * LineMag );
 
   
    Intersection.x = LineStart.x + U * ( LineEnd.x - LineStart.x );
    Intersection.y = LineStart.y + U * ( LineEnd.y - LineStart.y );
    Intersection.z = LineStart.z + U * ( LineEnd.z - LineStart.z );
 	Intersection.w = LineStart.w + U * ( LineEnd.w - LineStart.w );
 	return Intersection;
}


vec4 doPerspectiveDivisionAndViewportTransformation(vec4 v)
{
	v.x /= v.w;
	v.y /= v.w;
	v.z /= v.w;

	vec4 winpos;
	winpos.x= viewport.x + (1.0 + v.x) * viewport.z / 2.0;
	winpos.y= viewport.y + (1.0 + v.y) * viewport.w / 2.0;
	winpos.z= (1.0 + v.z) / 2.0;

	return winpos;
}

void main()
{
	vec4 texcoord = gl_TexCoord[0];
	
	mat4 frameMVP;
	frameMVP[0]= ModelViewMatrixOfFrameColumn0;
	frameMVP[1]= ModelViewMatrixOfFrameColumn1;
	frameMVP[2]= ModelViewMatrixOfFrameColumn2;
	frameMVP[3]= ModelViewMatrixOfFrameColumn3;

	frameMVP =gl_ProjectionMatrix* frameMVP;

	//ok, compute fragment position of the vertex

	//first: perspective division
	vec4 bottomleft= doPerspectiveDivisionAndViewportTransformation(frameMVP*vertex00);
	vec4 bottomright= doPerspectiveDivisionAndViewportTransformation(frameMVP*vertex10);
	vec4 topleft= doPerspectiveDivisionAndViewportTransformation(frameMVP*vertex01);
	vec4 topright= doPerspectiveDivisionAndViewportTransformation(frameMVP*vertex11);
	vec4 winpos= doPerspectiveDivisionAndViewportTransformation(pos);

	vec4 p0= PointOnLineNearestToPoint(winpos, bottomleft, bottomright);
	vec4 p1= PointOnLineNearestToPoint(winpos, topleft, topright);
	vec4 p2= PointOnLineNearestToPoint(winpos, bottomleft, topleft);
	vec4 p3= PointOnLineNearestToPoint(winpos, bottomright, topright);
	float dw0= length(winpos-p0);
	float dw2= length(winpos-p2);

//alternative, which is slow
/*
	float d01_1=DistanceToPossibleIntersection(winpos.xy, p0.xy, winpos.xy, topleft.xy, topright.xy);
	float d01_2=DistanceToPossibleIntersection(winpos.xy, p0.xy, winpos.xy, bottomleft.xy, topleft.xy);
	float d01_3=DistanceToPossibleIntersection(winpos.xy, p0.xy, winpos.xy, bottomright.xy, topright.xy);

	float d23_1=DistanceToPossibleIntersection(winpos.xy, p2.xy, winpos.xy, topleft.xy, topright.xy);
	float d23_2=DistanceToPossibleIntersection(winpos.xy, p2.xy, winpos.xy, bottomleft.xy, bottomright.xy);
	float d23_3=DistanceToPossibleIntersection(winpos.xy, p2.xy, winpos.xy, bottomright.xy, topright.xy);

	float d01 = min(d01_1, min(d01_2, d01_3)) + dw0;
	float d23 = min(d23_1, min(d23_2, d23_3)) + dw2;
*/
	float d01 = length(p0-p1);
	float d23 = length(p2-p3);;

	texcoord.s=dw2 / d23;
	texcoord.t=1.0-(dw0 / d01);


	gl_FragColor = gl_Color * texture2D(tex0, texcoord.xy);
}
