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

tt1 = "Maximum number of crossover/crossunder. Each time price crosses support/resistance line, it is counted as a cross and when such crosses reaches 'Max crossover/crossunder' the support/resistance line is removed"

//@version=5
indicator('Map example', overlay=true, max_lines_count = 500)
lb = input.int(title = 'Left bars', defval = 5, minval = 2)
rb = input.int(title = 'Right bars', defval = 5, minval = 2)
max_cross_cnt = input.int(title = 'Max crossover/crossunder', defval = 3, minval = 1, maxval = 10, tooltip = tt1)
cross_cnt_as_width = input.bool(title = 'Set line width based on cross count', defval = true)
start_date = input.time(timestamp("01 Jan 1900"))

var map_sr_cross = map.new<int, int>()
var map_sr_type = map.new<int, string>()

var color_map = map.new<string, color>()
var style_map = map.new<string, string>()

if bar_index == 0
    color_map.put("S", color.green)
    color_map.put("R", color.red)
    style_map.put("S", line.style_solid)
    style_map.put("R", line.style_solid)
    style_map.put("StR", line.style_dotted)
    style_map.put("RtS", line.style_dotted)

//@function returns color
method get(map<string, color> clr, string key) => clr.get(key)
//@function returns line style
method get(map<string, string> style, string key) => style.get(key)
//@function Returns count of price crosses from a map
method count(map<int, int> cnt, int key) => cnt.get(key)
//@function increments cross count in a map
method increment(map<int, int> cnt, int key) => cnt.put(key, cnt.get(key) + 1)
//@function Returns type S=support, R=reistance from a map.
method get(map <int, string> types, int key) => types.get(key)
//@function sets type S=support, R=reistance in a map
method set(map <int, string> types, int key, string val ) => types.put(key, val)
//@function deletes a map element
method delete(map<int, int> lines, int key) => lines.remove(key)
method delete(map<int, string> lines, int key) => lines.remove(key)
//@function returns crossover/crossunder if price crosses swing point
method state(float pp) => math.max(open, close) > pp and math.min(open, close) < pp ? 'Crossover' : math.min(open, close) < pp and math.max(open, close) > pp ? 'Crossunder' : na
//@function manipulate support/resistance lines based on price action
method price_action(array<line> lines) =>
    size = lines.size()
    if(size > 0)
        for i = size - 1 to 0 
            price_point = line.get_y1(lines.get(i))
            state = price_point.state()
            if(not na(state))
                bar_id = line.get_x1(lines.get(i))
                if(map_sr_cross.count(bar_id) + 1 >= max_cross_cnt)
                    line.delete(lines.get(i))
                    map_sr_cross.delete(i)
                    map_sr_type.delete(i)
                if(map_sr_cross.count(bar_id) + 1 < max_cross_cnt)
                    this_sr_type = map_sr_type.get(bar_id)
                    map_sr_type.set(bar_id, this_sr_type == 'R' ? 'S' : 'R')
                    style_key = this_sr_type + 't' + (this_sr_type == 'R' ? 'S' : 'R')
                    map_sr_cross.increment(bar_id)
                    line.set_style(lines.get(i), style_map.get(style_key))
                    line.set_color(lines.get(i), color_map.get(this_sr_type == 'R' ? 'S' : 'R'))
                    line.set_width(lines.get(i), cross_cnt_as_width ? map_sr_cross.count(bar_id) : 1)

//main code
ph = ta.pivothigh(high, lb, rb)
pl = ta.pivotlow(low, lb, rb)

if(ph and time >= start_date)
    line.new(bar_index-rb, high[rb], bar_index, high[rb], color = color_map.get('R'),  style = style_map.get('R'), extend = extend.right)
    map_sr_cross.put(bar_index-rb, 0)
    map_sr_type.set(bar_index-rb, 'R')
    // map_sr_type.put(bar_index-rb, 'R')

if(pl and time >= start_date)
    line.new(bar_index-rb, low[rb], bar_index, low[rb], color = color_map.get('S'),  style = style_map.get('S'), extend = extend.right)
    map_sr_cross.put(bar_index-rb, 0)
    map_sr_type.set(bar_index-rb, 'S')
    // map_sr_type.put(bar_index-rb, 'S')

//manipulate support/resistance lines based on price action
line.all.price_action()
