// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Clipper.hpp"

#include "Polygon.hpp"
#include "Renderer.hpp"

namespace {

inline void clipEdge(sw::float4 &Vo, const sw::float4 &Vi, const sw::float4 &Vj, float di, float dj)
{
	float D = 1.0f / (dj - di);

	Vo.x = (dj * Vi.x - di * Vj.x) * D;
	Vo.y = (dj * Vi.y - di * Vj.y) * D;
	Vo.z = (dj * Vi.z - di * Vj.z) * D;
	Vo.w = (dj * Vi.w - di * Vj.w) * D;
}

void clipNear(sw::Polygon &polygon, bool depthClipNegativeOneToOne)
{
	const sw::float4 **V = polygon.P[polygon.i];
	const sw::float4 **T = polygon.P[polygon.i + 1];

	int t = 0;

	for(int i = 0; i < polygon.n; i++)
	{
		int j = i == polygon.n - 1 ? 0 : i + 1;

		float di = V[i]->z;
		float dj = V[j]->z;

		// When depthClipNegativeOneToOne is enabled, z is mapped to (z+w)/2.  Division by 2
		// is not done, as distances are relative as far as clipEdge is concerned.
		if(depthClipNegativeOneToOne)
		{
			di += V[i]->w;
			dj += V[j]->w;
		}

		if(di >= 0)
		{
			T[t++] = V[i];

			if(dj < 0)
			{
				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
		else
		{
			if(dj > 0)
			{
				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
	}

	polygon.n = t;
	polygon.i += 1;
}

void clipFar(sw::Polygon &polygon)
{
	const sw::float4 **V = polygon.P[polygon.i];
	const sw::float4 **T = polygon.P[polygon.i + 1];

	int t = 0;

	for(int i = 0; i < polygon.n; i++)
	{
		int j = i == polygon.n - 1 ? 0 : i + 1;

		float di = V[i]->w - V[i]->z;
		float dj = V[j]->w - V[j]->z;

		// When depthClipNegativeOneToOne is enabled, z is mapped to (z+w)/2.  We have:
		//
		//     w - (z+w)/2 = (w - z)/2
		//
		// But division by 2 is not done, as distances are relative as far as clipEdge is
		// concerned.  In short, no special handling is necessary.

		if(di >= 0)
		{
			T[t++] = V[i];

			if(dj < 0)
			{
				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
		else
		{
			if(dj > 0)
			{
				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
	}

	polygon.n = t;
	polygon.i += 1;
}

void clipLeft(sw::Polygon &polygon)
{
	const sw::float4 **V = polygon.P[polygon.i];
	const sw::float4 **T = polygon.P[polygon.i + 1];

	int t = 0;

	for(int i = 0; i < polygon.n; i++)
	{
		int j = i == polygon.n - 1 ? 0 : i + 1;

		float di = V[i]->w + V[i]->x;
		float dj = V[j]->w + V[j]->x;

		if(di >= 0)
		{
			T[t++] = V[i];

			if(dj < 0)
			{
				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
		else
		{
			if(dj > 0)
			{
				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
	}

	polygon.n = t;
	polygon.i += 1;
}

void clipRight(sw::Polygon &polygon)
{
	const sw::float4 **V = polygon.P[polygon.i];
	const sw::float4 **T = polygon.P[polygon.i + 1];

	int t = 0;

	for(int i = 0; i < polygon.n; i++)
	{
		int j = i == polygon.n - 1 ? 0 : i + 1;

		float di = V[i]->w - V[i]->x;
		float dj = V[j]->w - V[j]->x;

		if(di >= 0)
		{
			T[t++] = V[i];

			if(dj < 0)
			{
				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
		else
		{
			if(dj > 0)
			{
				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
	}

	polygon.n = t;
	polygon.i += 1;
}

void clipTop(sw::Polygon &polygon)
{
	const sw::float4 **V = polygon.P[polygon.i];
	const sw::float4 **T = polygon.P[polygon.i + 1];

	int t = 0;

	for(int i = 0; i < polygon.n; i++)
	{
		int j = i == polygon.n - 1 ? 0 : i + 1;

		float di = V[i]->w - V[i]->y;
		float dj = V[j]->w - V[j]->y;

		if(di >= 0)
		{
			T[t++] = V[i];

			if(dj < 0)
			{
				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
		else
		{
			if(dj > 0)
			{
				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
	}

	polygon.n = t;
	polygon.i += 1;
}

void clipBottom(sw::Polygon &polygon)
{
	const sw::float4 **V = polygon.P[polygon.i];
	const sw::float4 **T = polygon.P[polygon.i + 1];

	int t = 0;

	for(int i = 0; i < polygon.n; i++)
	{
		int j = i == polygon.n - 1 ? 0 : i + 1;

		float di = V[i]->w + V[i]->y;
		float dj = V[j]->w + V[j]->y;

		if(di >= 0)
		{
			T[t++] = V[i];

			if(dj < 0)
			{
				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
		else
		{
			if(dj > 0)
			{
				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
				T[t++] = &polygon.B[polygon.b++];
			}
		}
	}

	polygon.n = t;
	polygon.i += 1;
}

}  // anonymous namespace

namespace sw {

bool Clipper::Clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
{
	if(clipFlagsOr & CLIP_FRUSTUM)
	{
		if(clipFlagsOr & CLIP_NEAR) clipNear(polygon, draw.depthClipNegativeOneToOne);
		if(polygon.n >= 3)
		{
			if(clipFlagsOr & CLIP_FAR) clipFar(polygon);
			if(polygon.n >= 3)
			{
				if(clipFlagsOr & CLIP_LEFT) clipLeft(polygon);
				if(polygon.n >= 3)
				{
					if(clipFlagsOr & CLIP_RIGHT) clipRight(polygon);
					if(polygon.n >= 3)
					{
						if(clipFlagsOr & CLIP_TOP) clipTop(polygon);
						if(polygon.n >= 3)
						{
							if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon);
						}
					}
				}
			}
		}
	}

	return polygon.n >= 3;
}

}  // namespace sw
