//
// This source code is property of the Computer Graphics and Visualization
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
//
#include "dda_line_tool.h"
#include <algorithm>

#include <iostream>

// Initialize the tool and store a reference of a canvas_buffer
dda_line_tool::dda_line_tool(canvas_buffer &canvas) : tool_base(canvas)
{
	shape = TS_LINE;
}

// Draw a line from (x0, y0) to (x1, y1)
void dda_line_tool::draw(int x0, int y0, int x1, int y1)
{
	/************
	Task 3.1.1.    Implement the DDA algorithm to raster a line from (x0, y0)
	               to (x1, y1). To set a pixel use "canvas.set_pixel(x, y)" where
				   "x" and "y" is the desired pixel position. This method
				   handles border violations. Establish the standard case in the
				   first step. If you need to swap the value of two variables you
				   can use the method "std::swap(a, b)".
	Aufgabe 3.1.1. Implementieren Sie den DDA-Algorithmus um eine Linie von
	               (x0, y0) nach (x1, y1) zu rastern. Verwenden Sie
				   "canvas.set_pixel(x, y)" um einen Pixel zu setzen, wobei
				   "x" und "y" den gew�nschten Pixelpositionen entsprechen.
				   Diese Methode behandelt auch Randverletzungen. Stellen Sie zunaechst
				   den Standardfall her. Falls Sie den Wert zweier Variablen vertauschen
				   muessen koennen Sie daf�r die Methode "std::swap(a, b)" verwenden.
   	*************/

	/*
	int tmp;
	// check all different cases

	// mirror on x-achsis (y -> -y)
	if (x0 < x1 && y0 > y1)
	{
		y0 = -y0;
		y1 = -y1;

		float y = static_cast<float>(y0);
		float m = static_cast<float>(y1 - y0) / static_cast<float>(x1 - x0);

		// '<=' - because we need to include x1 as end location
		for (int x = x0; x <= x1; x++)
		{
			int i_y = static_cast<int>(y + 0.5f);
			// (y -> -y)
			canvas.set_pixel(x, -i_y);
			y += m;
		}
	}
	// rotate by 90° (x <-> -y)
	else if (x0 > x1 && y0 < y1)
	{
		tmp = x0;
		x0 = -y0;
		y0 = tmp;

		tmp = x1;
		x1 = -y1;
		y1 = tmp;

		float y = static_cast<float>(y0);
		float m = static_cast<float>(y1 - y0) / static_cast<float>(x1 - x0);

		// '<=' - because we need to include x1 as end location
		for (int x = x0; x <= x1; x++)
		{
			int i_y = static_cast<int>(y + 0.5f);
			// (x <-> -y)
			canvas.set_pixel(-i_y, x);
			y += m;
		}
	}
	// mirror on main diagonal (x <-> y)
	else if (x)
	{

	}
	// standard
	else
	{
	*/

	if (x0 > x1)
	{
		std::swap(x0, x1);
		std::swap(y0, y1);
	}

	float m = static_cast<float>(y1 - y0) / static_cast<float>(x1 - x0);

	std::cout << "anstieg " << m << std::endl;

	float y = static_cast<float>(y0);
	for (int x = x0; x < x1; x++)
	{
		canvas.set_pixel(x, static_cast<int>(y + 0.5f));
		y += m;
	}

	//}
}

// Put debug output into the stream "stream" to be displayed in the
// main window
void dda_line_tool::set_text(std::stringstream &stream)
{
	stream << "Tool: DDA-Line (click and drag mouse to draw)";
}