Vector2DrawTriangle
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RicardoSantos

//@version=5

// @description Functions to draw a triangle and manipulate its properties.
library(title='Vector2DrawTriangle')
// .
// references:
//      https://docs.unity3d.com/ScriptReference/Vector2.html
//      https://gist.github.com/winduptoy/a1aa09c3499e09edbd33
//      https://github.com/dogancoruh/Javascript-Vector2/blob/master/js/vector2.js
//      https://gist.github.com/Dalimil/3daf2a0c531d7d030deb37a7bfeff454
//      https://gist.github.com/jeantimex/7fa22744e0c45e5df770b532f696af2d
//      https://gist.github.com/volkansalma/2972237
// .



//#region	Imports:																			

import RicardoSantos/CommonTypesMath/1 as TMath
import RicardoSantos/CommonTypesDrawing/1 as TDraw
import RicardoSantos/Vector2/1 as Vector2
import RicardoSantos/Vector2DrawLine/1 as line

//#endregion
//#region	Constructor:																		

// new				() {

// @function Draws a triangle with background fill using line prototype.
// @param a          v2     . Vector2 object, in the form `(x, y)`.
// @param b          v2     . Vector2 object, in the form `(x, y)`.
// @param c          v2     . Vector2 object, in the form `(x, y)`.
// @param xloc       string . Type of axis unit, bar_index or time.
// @param bg_color   color  . Color of the background.
// @param line_color color  . Color of the line.
// @param line_style string . Style of the line.
// @param line_width int    . Width of the line.
// @returns Triangle object.
export new (
 TMath.Vector2 a                     , 
 TMath.Vector2 b                     , 
 TMath.Vector2 c                     , 
 string        xloc       = 'bi'     , 
 color         bg_color   = #2196f3, 
 color         line_color = #2196f3, 
 string        line_style = 'sol'    , 
 int           line_width = 1        ) =>
	TMath.Segment2 _ab = TMath.Segment2.new(a, b)
	TMath.Segment2 _bc = TMath.Segment2.new(c, b)
	TMath.Segment2 _ca = TMath.Segment2.new(c, a)
	line _line1 = line.new(_ab, xloc, extend.none, line_color, line_style, line_width)
	line _line2 = line.new(_bc, xloc, extend.none, line_color, line_style, line_width)
	line _line3 = line.new(_ca, xloc, extend.none, line_color, line_style, line_width)
	linefill _fill = linefill.new(_line1, _line2, bg_color)
	TDraw.Triangle.new(_line1, _line2, _line3, _fill)

// }
// copy				() {

// @function Copy a existing triangle object.
// @param this Triangle . Source triangle.
// @returns Triangle.
export method copy (TDraw.Triangle this) =>
	TDraw.Triangle.copy(this)

// }
// delete			() {

// @function Delete all the underlying object properties (line, fill).
// @param this	`Triangle`	Source triangle.
// @returns `void`.
export method delete (TDraw.Triangle this) =>
	this.ab.delete()
	this.bc.delete()
	this.ca.delete()
	this.fill.delete()

// }

//#endregion
//#region	Properties:																			

// set_position_a () {

// @function Set the position of corner `a` (modifies source triangle).
// @param this Triangle . Source triangle.
// @param x    int      . Value at the x axis.
// @param y    float    . Value at the y axis.
// @returns Source Triangle.
export method set_position_a (TDraw.Triangle this, int x, float y) =>
	this.ab.set_xy1(x, y)
	this.ca.set_xy2(x, y)
	this

// @function Set the position of corner `a` (modifies source triangle).
// @param this     Triangle . Source triangle.
// @param position Vector2  . New position.
// @returns Source Triangle.
export method set_position_a (TDraw.Triangle this, TMath.Vector2 position) =>
	this.ab.set_xy1(int(position.x), position.y)
	this.ca.set_xy2(int(position.x), position.y)
	this

// }
// set_position_b () {

// @function Set the position of corner `b` (modifies source triangle).
// @param this Triangle . Source triangle.
// @param x    int      . Value at the x axis.
// @param y    float    . Value at the y axis.
// @returns Source Triangle.
export method set_position_b (TDraw.Triangle this, int x, float y) =>
	this.ab.set_xy2(x, y)
	this.bc.set_xy2(x, y) // the origin/target are inverted because of the fill
	this

// @function Set the position of corner `b` (modifies source triangle).
// @param this     Triangle . Source triangle.
// @param position Vector2  . New position.
// @returns Source Triangle.
export method set_position_b (TDraw.Triangle this, TMath.Vector2 position) =>
	this.ab.set_xy2(int(position.x), position.y)
	this.bc.set_xy2(int(position.x), position.y) // the origin/target are inverted because of the fill
	this

// }
// set_position_c () {

// @function Set the position of corner `c` (modifies source triangle).
// @param this Triangle . Source triangle.
// @param x    int      . Value at the x axis.
// @param y    float    . Value at the y axis.
// @returns Source Triangle.
export method set_position_c (TDraw.Triangle this, int x, float y) =>
	this.bc.set_xy1(x, y) // the origin/target are inverted because of the fill
	this.ca.set_xy1(x, y)
	this

// @function Set the position of corner `c` (modifies source triangle).
// @param this     Triangle . Source triangle.
// @param position Vector2  . New position.
// @returns Source Triangle.
export method set_position_c (TDraw.Triangle this, TMath.Vector2 position) =>
	this.bc.set_xy1(int(position.x), position.y) // the origin/target are inverted because of the fill
	this.ca.set_xy1(int(position.x), position.y)
	this

// }
// set_line_style () {

// @function Update triangle style options (modifies Source triangle).
// @param this       Triangle . Source triangle.
// @param bg_color   color    . Color of the background.
// @param line_color color    . Color of the line.
// @param line_style string   . Style of the line.
// @param line_width int      . Width of the line.
// @returns Source Triangle.
export method set_style (
 TDraw.Triangle this                  ,
 color          bg_color   = #2196f3, 
 color          line_color = #2196f3, 
 string         line_style = 'sol'    , 
 int            line_width = 1        ) =>
	linefill.set_color(this.fill, bg_color)
	this.ab.set_color(line_color) , this.ab.set_width(line_width) , this.ab.set_style(line_style)
	this.bc.set_color(line_color) , this.bc.set_width(line_width) , this.bc.set_style(line_style)
	this.ca.set_color(line_color) , this.ca.set_width(line_width) , this.ca.set_style(line_style)
	this

// TEST: 20230218 RS
// tstyle = input.string('sol', options=[line.style_solid, line.style_dashed, line.style_dotted])
// tlinecol = input.color(#e3e3e3)
// tbgcol = input.color(#e3e3e3)
// tlinew = input.int(1)
// if barstate.islast
//     _a = Vector2.new(bar_index + 0.0, 0.0)
//     _b = Vector2.new(bar_index + 100.0, 50.0)
//     _c = Vector2.new(bar_index + 200.0, 0.0)
//     tri = new(_a, _b, _c)
//     tri.set_style(tbgcol, tlinecol, tstyle, tlinew)

// }
// set_bg_color   () {

// @function Update triangle style options (modifies Source triangle).
// @param this       Triangle . Source triangle.
// @param bg_color   color    . Color of the background.
// @returns Source Triangle.
export method set_bg_color (
 TDraw.Triangle this                  ,
 color          bg_color   = #2196f3) =>
	linefill.set_color(this.fill, bg_color)
	this

// }
// set_line_color () {

// @function Update triangle style options (modifies Source triangle).
// @param this       Triangle . Source triangle.
// @param line_color color    . Color of the line.
// @returns Source Triangle.
export method set_line_color (
 TDraw.Triangle this                  ,
 color          line_color = #2196f3) =>
	this.ab.set_color(line_color)
	this.bc.set_color(line_color)
	this.ca.set_color(line_color)
	this

// }
// set_line_style () {

// @function Update triangle style options (modifies Source triangle).
// @param this       Triangle . Source triangle.
// @param line_style string   . Style of the line.
// @returns Source Triangle.
export method set_line_style (
 TDraw.Triangle this                  ,
 string         line_style = 'sol'    ) =>
	this.ab.set_style(line_style)
	this.bc.set_style(line_style)
	this.ca.set_style(line_style)
	this

// }
// set_line_width () {

// @function Update triangle style options (modifies Source triangle).
// @param this       Triangle . Source triangle.
// @param line_width int      . Width of the line.
// @returns Source Triangle.
export method set_line_width (
 TDraw.Triangle this                  ,
 int            line_width = 1        ) =>
	this.ab.set_width(line_width)
	this.bc.set_width(line_width)
	this.ca.set_width(line_width)
	this

// }

//#endregion
//#region	Instance Methods:																	

// move           () {

// @function Move triangle by provided amount (modifies source triangle).
// @param this   Triangle . Source triangle.
// @param x      float    . Amount to move the vertices of the triangle in the x axis.
// @param y      float    . Amount to move the vertices of the triangle in the y axis.
// @returns Source Triangle.
export method move (TDraw.Triangle this, int x=0, float y=0.0) =>
	int _ax = this.ab.get_x1() , float _ay = this.ab.get_y1()
	int _bx = this.bc.get_x2() , float _by = this.bc.get_y2() // the origin/target are inverted because of the fill
	int _cx = this.ca.get_x1() , float _cy = this.ca.get_y1()
	this.ab.set_xy1(_ax + x, _ay + y) , this.ab.set_xy2(_bx + x, _by + y)
	this.bc.set_xy2(_bx + x, _by + y) , this.bc.set_xy1(_cx + x, _cy + y) // the origin/target are inverted because of the fill
	this.ca.set_xy1(_cx + x, _cy + y) , this.ca.set_xy2(_ax + x, _ay + y)
	this

// @function Move triangle by provided amount (modifies source triangle).
// @param this   Triangle . Source triangle.
// @param amount Vector2  . Amount to move the vertices of the triangle in the x and y axis.
// @returns Source Triangle.
export method move (TDraw.Triangle this, TMath.Vector2 amount) =>
	this.move(int(amount.x), amount.y)

// TEST: 20230218 RS
// mx = input.int(0, step=10)
// my = input.float(0.0, step=10.0)
// if barstate.islast
//     _a = Vector2.new(bar_index + 0.0, 0.0)
//     _b = Vector2.new(bar_index + 100.0, 50.0)
//     _c = Vector2.new(bar_index + 200.0, 0.0)
//     tri = new(_a, _b, _c)
//     tri.move(mx, my)

// }
// rotate_around  () {

// @function Rotate source triangle around a center (modifies source triangle).
// @param this   Triangle . Source triangle.
// @param center Vector2  . Center coordinates of the rotation.
// @param angle  float    . Value of angle in degrees.
// @returns Source Triangle.
export method rotate_around (TDraw.Triangle this, TMath.Vector2 center, float angle) =>
	int _ax = this.ab.get_x1() , float _ay = this.ab.get_y1()
	int _bx = this.bc.get_x2() , float _by = this.bc.get_y2() // the origin/target are inverted because of the fill
	int _cx = this.ca.get_x1() , float _cy = this.ca.get_y1()
	_a = Vector2.new(_ax, _ay).rotate_around(center, angle)
	_b = Vector2.new(_bx, _by).rotate_around(center, angle)
	_c = Vector2.new(_cx, _cy).rotate_around(center, angle)
	this.ab.set_xy1(int(_a.x), _a.y) , this.ab.set_xy2(int(_b.x), _b.y)
	this.bc.set_xy2(int(_b.x), _b.y) , this.bc.set_xy1(int(_c.x), _c.y) // the origin/target are inverted because of the fill
	this.ca.set_xy1(int(_c.x), _c.y) , this.ca.set_xy2(int(_a.x), _a.y)
	this

// @function Rotate source triangle around a center (modifies source triangle).
// @param this     Triangle . Source triangle.
// @param center_x int      . Center coordinates of the rotation.
// @param center_y float    . Center coordinates of the rotation.
// @param angle    float    . Value of angle in degrees.
// @returns Source Triangle.
export method rotate_around (TDraw.Triangle this, int center_x, float center_y, float angle) =>
	this.rotate_around(Vector2.new(center_x, center_y), angle)

// TEST: 20230218 RS
// mx = input.int(50, step=10)
// my = input.float(50.0, step=10.0)
// degree = input.float(0.0, step=10.0)
// if barstate.islast
//     _a = Vector2.new(bar_index + 0.0, 0.0)
//     _b = Vector2.new(bar_index + 100.0, 50.0)
//     _c = Vector2.new(bar_index + 200.0, 0.0)
//     _center = Vector2.new(bar_index + mx, my)
//     tri = new(_a, _b, _c)
//     tri.rotate_around(_center, degree)

// }

//#endregion

