FunctionGeometricLineDrawings
// 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 Methods to draw geometric objects.

library(title='FunctionGeometricLineDrawings')

// @function deletes all lines in array.
// @param lines line array, array with line objects to delete.
// @returns void.
export array_delete_all_lines(line[] lines) =>
    int _size = array.size(lines)
    for _i = 0 to _size-1
        line.delete(array.get(lines, _i))

// @function Draw a Triangle with 3 vector2D(x, y) coordinates.
// @param sample_x int array, triangle sample data X coordinate values.
// @param sample_y float array, triangle sample data Y coordinate values.
// @param xloc string, defaultoptions=xloc.bar_index, xloc.bar_time. 
// @param extend string, default=extend.none,  options=(extend.none, extend.right, extend.left, extend.both).
// @param color color, default= 
// @param style options line.style_solid, line.style_dotted, line.style_dashed, line.style_arrow_left, line.style_arrow_right, line.style_arrow_both
// @param width width in pixels.
// @returns line array
export triangle (int[] sample_x, float[] sample_y, string xloc=xloc.bar_index, string extend=extend.none, color color=#252525, string style=line.style_solid, int width=1) => //{
    int _size_x = array.size(sample_x)
    int _size_y = array.size(sample_y)
    //
    switch
        (_size_x != 3) => runtime.error('FunctionGeometricLineDrawings -> triangle(): "sample_x" has the wrong size.')
        (_size_x != _size_y) => runtime.error('FunctionGeometricLineDrawings -> triangle(): "sample_x" and "sample_y" size does not match.')
    //
    var line[] _triangle = array.new_line(3)
    int _x1 = array.get(sample_x, 0), int _x2 = array.get(sample_x, 1), int _x3 = array.get(sample_x, 2)
    float _y1 = array.get(sample_y, 0), float _y2 = array.get(sample_y, 1), float _y3 = array.get(sample_y, 2)
    //  draw the lines:
    array.set(_triangle, 0, line.new(x1=_x1, y1=_y1, x2=_x2, y2=_y2, xloc=xloc, extend=extend, color=color, style=style, width=width))
    array.set(_triangle, 1, line.new(x1=_x2, y1=_y2, x2=_x3, y2=_y3, xloc=xloc, extend=extend, color=color, style=style, width=width))
    array.set(_triangle, 2, line.new(x1=_x3, y1=_y3, x2=_x1, y2=_y1, xloc=xloc, extend=extend, color=color, style=style, width=width))
    _triangle
//{ usage:
show_triangle = input(true)
triangle_x1 = input(defval=4)
triangle_y1 = input(defval=4.0)
triangle_x2 = input(defval=0)
triangle_y2 = input(defval=18.0)
triangle_x3 = input(defval=8)
triangle_y3 = input(defval=15.0)
triangle_xloc = input.string(defval=xloc.bar_index, options=[xloc.bar_index, xloc.bar_time])
triangle_xtend = input.string(defval=extend.none, options=[extend.none, extend.right, extend.left, extend.both])
triangle_style = input.string(defval=line.style_solid, options=[line.style_solid, line.style_dotted, line.style_dashed, line.style_arrow_left, line.style_arrow_right, line.style_arrow_both])
triangle_width = input.int(2, minval=0)
var line[] triangle_lines = array.new_line(3)
if show_triangle 
    _adjust_x1 = triangle_xloc == xloc.bar_index ? bar_index - triangle_x1 : timenow + triangle_x1 * 60000
    _adjust_x2 = triangle_xloc == xloc.bar_index ? bar_index - triangle_x2 : timenow + triangle_x2 * 60000
    _adjust_x3 = triangle_xloc == xloc.bar_index ? bar_index - triangle_x3 : timenow + triangle_x3 * 60000
    _X = array.from(_adjust_x1, _adjust_x2, _adjust_x3)
    _Y = array.from(triangle_y1, triangle_y2, triangle_y3)
    array_delete_all_lines(triangle_lines)
    triangle_lines := triangle(_X, _Y, triangle_xloc, triangle_xtend, color.new(#5555ff, 50), triangle_style, triangle_width)
//{ remarks:
//              (x2, y2)
//                  ┐
//                ∕ │
//        Side1 ∕   │ Side2
//            ⁄     │
//          └───────┘
//    (x1,y1) Side3 (x3, y3)
//}}}

// @function Draw a Trapezoid with 4 vector2D(x, y) coordinates:
// @param sample_x int array, trapezoid sample data X coordinate values.
// @param sample_y float array, trapezoid sample data Y coordinate values.
// @param xloc string, defaultoptions=xloc.bar_index, xloc.bar_time. 
// @param extend string, default=extend.none,  options=(extend.none, extend.right, extend.left, extend.both).
// @param color color, default= 
// @param style options line.style_solid, line.style_dotted, line.style_dashed, line.style_arrow_left, line.style_arrow_right, line.style_arrow_both
// @param width width in pixels.
// @returns line array
export trapezoid (int[] sample_x, float[] sample_y, string xloc=xloc.bar_index, string extend=extend.none, color color=#252525, string style=line.style_solid, int width=1) => //{
    int _size_x = array.size(sample_x)
    int _size_y = array.size(sample_y)
    //
    switch
        (_size_x != 4) => runtime.error('FunctionGeometricLineDrawings -> trapezoid(): "sample_x" has the wrong size.')
        (_size_x != _size_y) => runtime.error('FunctionGeometricLineDrawings -> trapezoid(): "sample_x" and "sample_y" size does not match.')
    //
    var line[] _trapezoid = array.new_line(3)
    int _x1 = array.get(sample_x, 0), int _x2 = array.get(sample_x, 1), int _x3 = array.get(sample_x, 2), int _x4 = array.get(sample_x, 3)
    float _y1 = array.get(sample_y, 0), float _y2 = array.get(sample_y, 1), float _y3 = array.get(sample_y, 2), float _y4 = array.get(sample_y, 3)
    //  draw the lines:
    array.set(_trapezoid, 0, line.new(x1=_x1, y1=_y1, x2=_x2, y2=_y2, xloc=xloc, extend=extend, color=color, style=style, width=width))
    array.set(_trapezoid, 1, line.new(x1=_x2, y1=_y2, x2=_x3, y2=_y3, xloc=xloc, extend=extend, color=color, style=style, width=width))
    array.set(_trapezoid, 2, line.new(x1=_x3, y1=_y3, x2=_x4, y2=_y4, xloc=xloc, extend=extend, color=color, style=style, width=width))
    array.set(_trapezoid, 2, line.new(x1=_x4, y1=_y4, x2=_x1, y2=_y1, xloc=xloc, extend=extend, color=color, style=style, width=width))
    _trapezoid
//{ usage:
show_trapezoid = input(true)
trapezoid_x1 = input(defval=15)
trapezoid_y1 = input(defval=4.0)
trapezoid_x2 = input(defval=10)
trapezoid_y2 = input(defval=25.0)
trapezoid_x3 = input(defval=5)
trapezoid_y3 = input(defval=20.0)
trapezoid_x4 = input(defval=2)
trapezoid_y4 = input(defval=2.0)
trapezoid_xloc = input.string(defval=xloc.bar_index, options=[xloc.bar_index, xloc.bar_time])
trapezoid_xtend = input.string(defval=extend.none, options=[extend.none, extend.right, extend.left, extend.both])
trapezoid_style = input.string(defval=line.style_dashed, options=[line.style_solid, line.style_dotted, line.style_dashed, line.style_arrow_left, line.style_arrow_right, line.style_arrow_both])
trapezoid_width = input.int(2, minval=0)
var line[] trapezoid_lines = array.new_line(4)
if show_trapezoid and barstate.islast and barstate.ishistory[1]
    _adjust_x1 = trapezoid_xloc == xloc.bar_index ? bar_index - trapezoid_x1 : timenow + trapezoid_x1 * 60000
    _adjust_x2 = trapezoid_xloc == xloc.bar_index ? bar_index - trapezoid_x2 : timenow + trapezoid_x2 * 60000
    _adjust_x3 = trapezoid_xloc == xloc.bar_index ? bar_index - trapezoid_x3 : timenow + trapezoid_x3 * 60000
    _adjust_x4 = trapezoid_xloc == xloc.bar_index ? bar_index - trapezoid_x4 : timenow + trapezoid_x4 * 60000
    _X = array.from(_adjust_x1, _adjust_x2, _adjust_x3, _adjust_x4)
    _Y = array.from(trapezoid_y1, trapezoid_y2, trapezoid_y3, trapezoid_y4)
    array_delete_all_lines(trapezoid_lines)
    trapezoid_lines := trapezoid(_X, _Y, trapezoid_xloc, trapezoid_xtend, color.new(#ff5522, 50), trapezoid_style, trapezoid_width)
//{ ramarks:
//    (x2,y2) Side2 (x3, y3)
//          ┌───────┐
//          │       │
//   Side1  │       │ Side3
//          │       │
//          └───────┘
//    (x1,y1) Side4 (x4, y4)
//}}}
