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

//@version=5

library("BoxLine_Lib")
// @description : personal Library for line and box built in functions

// @function get [x1: y1,x2,y2] in a tuple
// @param line line
// @returns tuple of [x1,y1,x2,y2]
export LineXY(line line) =>
    x1 = line.get_x1(line)
    x2 = line.get_x2(line)
    y1 = line.get_y1(line)
    y2 = line.get_y2(line)
    [x1,y1,x2,y2]
    

// @function Create line with only the y1 value(when line == na)
//  when line != na set x1,y1,x2,y2 individually just 1 or all
//  - use just the line value to set the x2 to current bar or time will set to time
//    will auto pick xloc.bar_index or xloc.bar_time if not used by checking if 
//    if x1 or x2 is > a number bar index couldnt be i.e. 1000000
// @param line x1 y1 x2 y2 xloc extend color style width
// @returns : Line
export Line(int x1 = na,float y1 = na,int x2 = na,float y2 = na,
         string extend = extend.none,color color = #000000,
         string style = line.style_solid,int width = 1,line line = na, bool delete = true) =>
    
    var line Line = na
    
    bt = time_close - time
    x = na(x1) ? time : x1 
    y = na(y1) ? close : y1
    xx = na(x2) ? x > 100000 ? last_bar_time + (50*bt) : last_bar_index + 50 : x2
    yy = na(y2) ? y : y2
    xloc = x > 100000 ? xloc.bar_time : xloc.bar_index
    
    if not na(line)
        if na(x1)
            x := line.get_x1(line)
        if na(y1)
            y := line.get_y1(line)
        if na(x2)
            xx := line.get_x2(line) 
            if xx == last_bar_index[1]
                xx += 1
            if xx == last_bar_time[1]
                xx += bt
        if na(y2)
            yy := y
        if delete
            line.delete(line)

    Line := line.new(
     x1     = x,
     y1     = y,
     x2     = xx,
     y2     = yy,
     xloc   = xloc,
     extend = extend,
     color  = color,
     style  = style,
     width  = width)
    
    Line



// @function get [left,top,right,bottom] in a tuple
// @param box box
// @returns  tuple of [left,top,right,bottom]
export BoxXY(box box) =>
    left = box.get_left(box)
    top = box.get_top(box)
    right = box.get_right(box)
    bottom = box.get_bottom(box)
    [left,top,right,bottom] 
    
// @function 
//  Create box with only the top,bottom value(when box == na)
//  when box != na set left,top,right,bottom individually just 1 or all
//  - use just the box value to set the right to current bar or time, will set to time
//    if right is above a number that a bar_index wouldnt be above i.e. 1000000
// @param box left top right 
// bottom border_color border_width border_style extend xloc bgcolor text text_size text_color text_halign text_valign text_wrap
// @returns Box
export Box(int left = na,float top = na,int right = na,float bottom = na,
         color border_color = #00000073, int border_width = 1, string border_style = line.style_solid,
         string extend = extend.none, color bgcolor = #0000003f,
         string txt = '',string text_size = size.normal, color text_color = #000000,
         string text_halign = text.align_center,string text_valign = text.align_center,string text_wrap = text.wrap_auto, 
         box box = na, bool delete = true) =>
    
    var box Box = na
    
    bt = time_close - time
    Top = top
    Bottom = bottom
    Left = na(left) ? time : left 
    Right = na(right) ? Left > 100000 ? last_bar_time + (50*bt) : last_bar_index + 50 : right
    xloc = Left > 100000 ? xloc.bar_time : xloc.bar_index

    if not na(box)
        if na(left)
            Left := box.get_left(box)
        if na(bottom)
            Bottom := box.get_bottom(box)
        if na(top)
            Top := box.get_top(box)
        if na(right)
            Right := box.get_right(box)
        if delete
            box.delete(box)
        
    Box := box.new(
     left         = Left, 
     top          = top, 
     right        = Right, 
     bottom       = bottom, 
     border_color = border_color, 
     border_width = border_width,
     border_style = border_style,
     extend       = extend,  
     xloc         = xloc, 
     bgcolor      = bgcolor,
     text         = txt,
     text_size    = text_size, 
     text_color   = text_color,
     text_halign  = text_halign,
     text_valign  = text_valign,
     text_wrap    = text_wrap)
    
    Box


// @function get [x,y,txt] in a tuple
// @param label label
// @returns tuple of [x,y,txt]
export LabelXY(label label) =>
    txt = label.get_text(label)
    x = label.get_x(label)
    y = label.get_y(label)
    [x,y,txt]
    
// @function Create label with only the y1 value(when label == na)
//  when label != na set x1,y1,x2,y2 individually just 1 or all
//  - use just the label value to set the x2 to current bar or time will set to time
//    will auto pick xloc.bar_index or xloc.bar_time if not used by checking if 
//    if x1 or x2 is > a number bar index couldnt be i.e. 1000000
// @param label txt x y xloc.yloc color style textcolor size textalign tooltip text_font
// @returns  Label
export Label(int x = na,float y = na,string yloc = yloc.price,string txt = '',color color = #000000,
             string style = label.style_label_down ,color textcolor = #9acd32,string size = size.normal,
             string textalign = text.align_center,string tooltip = na,string text_font_family = font.family_default,
             label label = na, bool delete = true) =>
    
    var label Label = na

    _x = na(x) ? time : x 
    _y = na(y) ? close < open ? low : high : y
    _style = na(y) ? close < open ? label.style_label_down : label.style_label_up : style
    _text = txt
    _xloc = _x > 100000 ? xloc.bar_time : xloc.bar_index    
    
    if not na(label)
        if na(x)
            _x := label.get_x(label)
        if na(y)
            _y := label.get_y(label) 
        if na(txt)
            _text := label.get_text(label)
        if delete
            label.delete(label)

    Label := label.new(
     x                = _x,
     y                = _y,
     text             = _text,
     xloc             = _xloc,
     yloc             = yloc,
     color            = color,
     style            = style,
     textcolor        = textcolor,
     size             = size,
     textalign        = textalign,
     tooltip          = tooltip,
     text_font_family = text_font_family)
    
    Label


//Usage
var label label = na
var line line = na
var box box = na

box := Box(box = box,left = last_bar_index,txt = str.tostring(timenow),bottom = low,top = high)
line := Line(line = line,x1 = bar_index - 50,y1 = close, delete = true)


if barstate.islast
    label := Label(label = label,y = high,textalign = text.align_left,txt = str.tostring(bar_index) + ' | ' + str.format_time(timenow,'hh:mm:ssa','UTC-5'))

    [x,y,txt] = LabelXY(label)
    [left,top,right,bottom] = BoxXY(box)
    [x1,y1,x2,y2] = LineXY(line)

    label.set_text(label,label.get_text(label) + 
     str.format('\nLabel | [x:{0}] [y:{1}] [txt:{2}] \nBox | [left:{3}] [top:{4}] [right:{5}] [bottom:{6}]\nLine | [x1:{7}] [y1:{8}] [x2:{9}] [y2:{10}]',x,y,txt,left,top,right,bottom,x1,y1,x2,y2))



 




