Copy/Paste Levels
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © SamRecio

//@version=5
indicator("Copy/Paste Levels", overlay = true, max_lines_count = 500, max_labels_count = 500)

//Format = Ticker,Color,Style,Width(Negative Numbers),Text*,lvl1,lvl2,lvl3;
//*No Commas(,) or semi-colons(;)...for obvious reasons...
//Sample//
//qqq, , , , ,325;Qqq,red, , , ,325.5;QqQ, ,dotted, , ,326.0;QQQ,blue,dashed,-2,Hello World!,326.50;qqQ,green,solid,-10,text here,327,327.5,328;

//Inputs/////////////////////////////////////////////////////////////////
paste = str.upper(input.text_area("", title = "Input Levels:", confirm = true, tooltip = "Format:\nTicker,Color,Style,-Width,Text*,lvl1,lvl2,lvl3;\n*No Commas(,) or semi-colons(;)"))
lab_size = input.string("small", title = "Label Size", options = ["tiny","small","normal","large","huge"], inline = "2")
lab_offset = input.int(10, title = "Label Offset", inline = "2")
z_op = input.int(90, title = "Zone Opacity", minval = 0, maxval = 100, inline = "3")
tog_lvl = input.bool(true, title = "Toggle Price Labels", inline = "3")

//No Level Message//////////////////////////////////////////////////////////////
if str.contains(paste,syminfo.ticker) == false
    runtime.error("No levels for this ticker. Please input levels or change ticker. Current Ticker: " + syminfo.ticker)
//Variable initialization///////////////////////////////////////////////////////
var line lvl_line = na
var label lvl_lab = na
var line z1 = na
var line z2 = na
//Color & Style Functions///////////////////////////////////////////////////////
colorpicker(_input) =>
    _input == "RED"?color.red:
     _input == "ORANGE"?color.orange:
     _input == "YELLOW"?color.yellow:
     _input == "GREEN"?color.green:
     _input == "BLUE"?color.blue:
     _input == "PURPLE"?color.fuchsia:
     _input == "WHITE"?color.white:
     _input == "BLACK"?color.rgb(0,0,0):
     _input == "GRAY"?color.gray:
     chart.fg_color
stylepicker(_input) =>
    _input == "SOLID"?line.style_solid:
     _input == "DASHED"?line.style_dashed:
     _input == "DOTTED"?line.style_dotted:
     str.contains(_input,"SOLID")?line.style_solid:
     str.contains(_input,"DASHED")?line.style_dashed:
     str.contains(_input,"DOTTED")?line.style_dotted:
     line.style_solid
////////////////////////////////////////////////////////////////////////////////
//Delete all lines & Labels
a_allLines = line.all
if array.size(a_allLines) > 0
	for i = 0 to array.size(a_allLines) - 1
		line.delete(array.get(a_allLines, i))
a_allLabels = label.all
if array.size(a_allLabels) > 0
	for i = 0 to array.size(a_allLabels) - 1
		label.delete(array.get(a_allLabels, i))
////////////////////////////////////////////////////////////////////////////////
//Line and label drawing
split = str.split(paste,";")
for i = 0 to array.size(split) - 1 
    split_get = array.get(split,i)
    small_split = str.split(split_get,",")
    if array.size(small_split) > 5
        ssf = str.replace_all(array.get(small_split,0)," ","")
        if (ssf == syminfo.ticker) or (ssf == syminfo.tickerid)  or (ssf == "\n" + syminfo.ticker) or (ssf == "\n" + syminfo.tickerid)
            for e = 5 to array.size(small_split) - 1
                lvl = str.replace_all(array.get(small_split,e)," ","")
                co = colorpicker(str.replace_all(array.get(small_split,1)," ",""))
                sty = stylepicker(str.replace_all(array.get(small_split,2)," ",""))
                z = str.contains(str.replace_all(array.get(small_split,2)," ",""),"ZONE")
                thick = str.tonumber(str.replace_all(array.get(small_split,3)," ","")) < 0? str.tonumber(str.replace_all(array.get(small_split,3)," ","")) * -1:1
                txt = tog_lvl?array.get(small_split,4) +" "+ str.format("{0,number,currency}",str.tonumber(lvl)):array.get(small_split,4)
                if str.tonumber(lvl) > 0 and (z == false)
                    lvl_line := line.new(bar_index,str.tonumber(lvl),bar_index+1,str.tonumber(lvl), extend = extend.right, color = co, style = sty, width = int(thick))
                    lvl_lab := label.new(bar_index + lab_offset, str.tonumber(lvl), text = txt , color = color.new(color.black,100), size = lab_size, textcolor = co, style = label.style_label_lower_left)    
                if z and (array.size(small_split) == 7) and (e == 6)
                    z_lvl1 = math.max(str.tonumber(str.replace_all(array.get(small_split,5)," ","")),str.tonumber(str.replace_all(array.get(small_split,6)," ","")))
                    z_lvl2 = math.min(str.tonumber(str.replace_all(array.get(small_split,5)," ","")),str.tonumber(str.replace_all(array.get(small_split,6)," ","")))
                    z_txt = tog_lvl?array.get(small_split,4) +" "+ str.format("{0,number,currency}",z_lvl2) + " - " + str.format("{0,number,currency}",z_lvl1):array.get(small_split,4)
                    lvl_lab := label.new(bar_index + lab_offset, z_lvl1, text = z_txt , color = color.new(color.black,100), size = lab_size, textcolor = co, style = label.style_label_lower_left)   
                    z1 := line.new(bar_index,z_lvl1,bar_index+1,z_lvl1, extend = extend.right, color = co, style = sty, width = int(thick))
                    z2 := line.new(bar_index,z_lvl2,bar_index+1,z_lvl2, extend = extend.right, color = co, style = sty, width = int(thick))
                    linefill.new(z1,z2, color = color.new(co,z_op))
