// 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)
{
	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;

		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;

		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 {

unsigned int Clipper::ComputeClipFlags(const float4 &v)
{
	return ((v.x > v.w) ? CLIP_RIGHT : 0) |
	       ((v.y > v.w) ? CLIP_TOP : 0) |
	       ((v.z > v.w) ? CLIP_FAR : 0) |
	       ((v.x < -v.w) ? CLIP_LEFT : 0) |
	       ((v.y < -v.w) ? CLIP_BOTTOM : 0) |
	       ((v.z < 0) ? CLIP_NEAR : 0) |
	       Clipper::CLIP_FINITE;  // FIXME: xyz finite
}

bool Clipper::Clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
{
	if(clipFlagsOr & CLIP_FRUSTUM)
	{
		if(clipFlagsOr & CLIP_NEAR) clipNear(polygon);
		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
