using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace SketchAssistant
{
public class RedrawAssistant
{
///
/// The lines of the left image, with a boolean indicating if they have been redrawn
/// and an integer that is the same as the line id of the respective line in the right image.
///
List> linesToRedraw;
///
/// The Start and End points of all lines in linesToRedraw in the same order.
///
List, HashSet>> startAndEndPoints;
///
/// A Hashtable for quick lookup for a line id and its respective tuple in linesToRedraw
///
Hashtable redrawnLineLookupTable;
///
/// The position of the line currently being redrawn in the startAndEndPoints
/// & linesToRedraw lists. -1 if no line is being redrawn.
///
int lineBeingRedrawn;
///
/// The id of the line being drawn on the right side. -1 if no line is being drawn.
///
int currentLineID;
///
/// Whether or not the user is currently redrawing a line.
///
bool currentlyRedrawing;
///
/// Whether or not the RedrawAssistant is active.
///
bool isActive;
///
/// The radius of the markers for redrawing.
///
int markerRadius = 5;
///
/// The Constructor for an inactive RedrawAssistant.
///
public RedrawAssistant()
{
isActive = false;
}
///
/// The constructor for an active RedrawAssistant
///
/// The lines that shall be redrawn
public RedrawAssistant(List redrawItem)
{
linesToRedraw = new List>();
startAndEndPoints = new List, HashSet>>();
isActive = true;
currentlyRedrawing = false;
lineBeingRedrawn = -1;
redrawnLineLookupTable = new Hashtable();
foreach (Line line in redrawItem)
{
linesToRedraw.Add(new Tuple(line, false, -1));
}
SetMarkerRadius(5);
}
///
/// Initialization function that returns the initial list of overlay points.
///
/// The radius of the points.
/// The list of overlay points.
public List>> Initialize(int mRad)
{
if (isActive)
{
List>> retList = new List>>();
SetMarkerRadius(mRad);
foreach(Tuple, HashSet> tup in startAndEndPoints)
{
retList.Add(new Tuple>(false, tup.Item1));
retList.Add(new Tuple>(false, tup.Item2));
}
return retList;
}
return null;
}
///
/// The main functionality of the RedrawAssistant, which updates the Assistant according to the inputs given.
///
/// The current position of the cursor, as a point
/// The lines on the right canvas
/// The id of the line currently being drawn.
/// A boolean to indicate that the line is finished
/// A list containing the overlay items and if they should be drawn.
/// The updated List of overlay items, or the same list if no changes need to be done,
/// along with a boolean indicating if something was changed
public Tuple>>> Tick(Point currentPoint, List> rightLines, int currLineID, bool lineFinished,
List>> overlayItems)
{
if (!isActive) { return new Tuple>>>(false, overlayItems); }
if (!currentlyRedrawing)
{
}
/*
Tuple newLineTuple = null;
var returnAllStartPoints = true;
CheckForUndrawnLines(rightLines);
// Checking if a startpoint is intersected
if (!currentlyRedrawing)
{
for (int i = 0; i < linesToRedraw.Count; i++)
{
Tuple tup = linesToRedraw[i];
if (!tup.Item2)
{
if (startAndEndPoints[i].Item1.Contains(currentPoint))
{
currentlyRedrawing = true;
lineBeingRedrawn = i;
currentLineID = currLineID;
returnList.Add(startAndEndPoints[i].Item1);
returnList.Add(startAndEndPoints[i].Item2);
returnAllStartPoints = false;
}
}
}
}
//Currently redrawing a line, but a line hasn't been finished drawing.
else if (!lineFinished)
{
returnList.Add(startAndEndPoints[lineBeingRedrawn].Item1);
returnList.Add(startAndEndPoints[lineBeingRedrawn].Item2);
returnAllStartPoints = false;
}
//Line is finished, check if it is in the correct endpoint
else if (currLineID == currentLineID && startAndEndPoints[lineBeingRedrawn].Item2.Contains(currentPoint))
{
newLineTuple = new Tuple(linesToRedraw[lineBeingRedrawn].Item1, true, currLineID);
currentlyRedrawing = false;
lineBeingRedrawn = -1;
currentLineID = -1;
}
//Line is finished, but not in the correct endpoint
else
{
currentlyRedrawing = false;
lineBeingRedrawn = -1;
currentLineID = -1;
}
//Replace the changed line tuple in linesToRedraw
if(newLineTuple != null)
{
var newLine = newLineTuple.Item1;
for (int i = 0; i < linesToRedraw.Count; i++)
{
var redrawLine = linesToRedraw[i].Item1;
if (redrawLine.GetID() == newLine.GetID()
&& redrawLine.GetStartPoint().Equals(newLine.GetStartPoint())
&& redrawLine.GetEndPoint().Equals(newLine.GetEndPoint()))
{
redrawnLineLookupTable.Add(currLineID, i);
linesToRedraw[i] = newLineTuple;
}
}
}
//Add all the startpoints to the list being returned
if (returnAllStartPoints)
{
for (int i = 0; i < linesToRedraw.Count; i++)
{
if (!linesToRedraw[i].Item2)
{
returnList.Add(startAndEndPoints[i].Item1);
}
}
}
return returnList;
*/
return new Tuple>>>(false, overlayItems);
}
///
/// A helping function which checks for lines where previously redrawn, but were removed from the image again.
///
/// The lines in the right image.
private void CheckForUndrawnLines(List> rightLines)
{
for (int i = 0; i < rightLines.Count; i++)
{
if (redrawnLineLookupTable.ContainsKey(rightLines[i].Item2.GetID()))
{
if (!rightLines[i].Item1)
{
int listPos = (int)redrawnLineLookupTable[rightLines[i].Item2.GetID()];
var oldTup = linesToRedraw[listPos];
linesToRedraw[listPos] = new Tuple(oldTup.Item1, false, -1);
}
else
{
int listPos = (int)redrawnLineLookupTable[rightLines[i].Item2.GetID()];
var oldTup = linesToRedraw[listPos];
linesToRedraw[listPos] = new Tuple(oldTup.Item1, true, rightLines[i].Item2.GetID());
}
}
}
}
///
/// A function to set the marker radius for the markers returned by the RedrawAssistant
///
/// The Radius of the markers.
public void SetMarkerRadius(int markerRad)
{
markerRadius = markerRad;
if (isActive)
{
startAndEndPoints = new List, HashSet>>();
foreach (Tuple tup in linesToRedraw)
{
startAndEndPoints.Add(CalculateStartAndEnd(tup.Item1));
}
}
}
///
/// Will calculate the start and endpoints of the given line.
///
/// The given line.
private Tuple, HashSet> CalculateStartAndEnd(Line line)
{
var circle0 = GeometryCalculator.FilledCircleAlgorithm(line.GetStartPoint(), markerRadius);
var circle1 = GeometryCalculator.FilledCircleAlgorithm(line.GetEndPoint(), markerRadius);
var currentLineEndings = new Tuple, HashSet>(circle0, circle1);
return currentLineEndings;
}
}
}