from elliptic_curve import *

plots = []

def is_too_far_away(x, y):
	return x > 100 or x < -100 or y > 100 or y < -100

def display_elliptic_curve(ax, curve):
	global plots
	plots += ax.plot(*curve.points(), color='red')

def display_elliptic_curve_over_finite_field(ax, curve):
	global plots
	xs, ys = curve.points()
	plots += [ax.scatter(
		xs,
		ys,
		color='red', s=20, marker='o'
	)]

def double_elliptic_curve(ax, curve, x, y):
	global plots
	p = curve.double(x, y)
	plots += ax.plot([x], [y], 'o')
	plots += [ax.axline(
		(x, y),
		(p[0], -p[1]),
		linestyle='--'
	)]
	if not is_too_far_away(*p):
		plots += [ax.axline(
			p,
			(p[0], p[1] + 1),
			linestyle='--'
		)]
		plots += ax.plot([p[0]], [p[1]], 'o')

def double_elliptic_curve_over_finite_field(ax, curve, x, y):
	pass

def clear():
	global plots
	for i in plots:
		i.remove()
	plots = []

def addition_elliptic_curve(ax, curve, x1, y1, x2, y2):
	global plots
	p = curve.add(x1, y1, x2, y2)
	plots += [ax.axline(
		(x1, y1),
		(x2, y2),
		linestyle='--'
	)]
	xa = [x1, x2]
	ya = [y1, y2]
	if not is_too_far_away(*p):
		xa.append(p[0])
		ya.append(p[1])
		plots += [ax.axline(
			(p[0], p[1]),
			(p[0], p[1] + 1),
			linestyle='--'
		)]
	plots += ax.plot(xa, ya, 'o')

def addition_elliptic_curve_over_finite_field(ax, curve, x1, y1, x2, y2):
	global plots
	p = curve.add(x1, y1, x2, y2)
	x_axis_intersection = intersection(x1, y1, x2, y2, 0, 0, 1, 0)
	limit_intersection  = intersection(x1, y1, x2, y2, 0, curve.mod-1, 1, curve.mod-1)
	print(x_axis_intersection, limit_intersection)
	plots += [ax.plot(
		(x_axis_intersection[0], limit_intersection[0]),
		(x_axis_intersection[1], limit_intersection[1]),
		linestyle='--'
	)]
	plots += ax.plot([p[0], p[1]], 'x')

def addition(ax, curve, x1, y1, x2, y2):
	if isinstance(curve, EllipticCurve):
		addition_elliptic_curve(ax, curve, x1, y1, x2, y2)
	elif isinstance(curve, EllipticCurveOverFiniteField):
		addition_elliptic_curve_over_finite_field(ax, curve, x1, y1, x2, y2)

def double(ax, curve, x, y):
	if isinstance(curve, EllipticCurve):
		double_elliptic_curve(ax, curve, x, y)
	elif isinstance(curve, EllipticCurveOverFiniteField):
		double_elliptic_curve_over_finite_field(ax, curve, x, y)

def display(ax, curve):
	if isinstance(curve, EllipticCurve):
		display_elliptic_curve(ax, curve)
	elif isinstance(curve, EllipticCurveOverFiniteField):
		display_elliptic_curve_over_finite_field(ax, curve)