from brparser import Keypress, Key, apply_mods_to_time, diff_range, HitCircleOsu, SliderOsu, SpinnerOsu


def get_keypresses(replay):
    keypresses = []
    button_1 = False
    button_2 = False
    for event in replay.replay_data:
        if (event.keys & Key.M1):
            if not button_1:
                button_1 = True
                init_1 = event.time
        else:
            if button_1:
                button_1 = False
                keypresses.append(Keypress(init_1, event.time))
        if (event.keys & Key.M2):
            if not button_2:
                button_2 = True
                init_2 = event.time
        else:
            if button_2:
                button_2 = False
                keypresses.append(Keypress(init_2, event.time))
    return keypresses


def get_kp_sliders(replay, beatmap):
    keypresses = get_keypresses(replay)
    hw_50 = int(diff_range(beatmap.od, 200, 150, 100, replay.mods))

    keypress_times = []
    sliderend_release_times = []
    hit_objs = beatmap.hit_objects

    kp_i = 0
    ho_i = 0

    while ho_i < len(hit_objs) and kp_i < len(keypresses):
        ho = hit_objs[ho_i]
        kp = keypresses[kp_i]

        if isinstance(ho, HitCircleOsu):
            end_time = ho.start_time + hw_50 + 1
        else:
            end_time = ho.end_time

        if kp.key_down < ho.start_time - 400:
            kp_i += 1
            continue

        if kp.key_down <= ho.start_time - hw_50:
            if isinstance(ho, SliderOsu):
                release_time = kp.key_up - ho.end_time
                sliderend_release_times.append(
                    apply_mods_to_time(release_time, replay.mods))
                while keypresses[kp_i].key_down < ho.end_time:
                    kp_i += 1
                    if kp_i >= len(keypresses):
                        break
            else:
                if isinstance(ho, HitCircleOsu):
                    keypress_time = kp.key_up - kp.key_down
                    keypress_times.append(apply_mods_to_time(keypress_time,
                                                             replay.mods))
                kp_i += 1
            ho_i += 1
        elif kp.key_down >= end_time:
            ho_i += 1
        else:
            if kp.key_down < ho.start_time + hw_50 and not isinstance(ho, SpinnerOsu):
                if isinstance(ho, SliderOsu):
                    release_time = kp.key_up - ho.end_time
                    sliderend_release_times.append(
                        apply_mods_to_time(release_time, replay.mods))
                    while keypresses[kp_i].key_down < ho.end_time:
                        kp_i += 1
                        if kp_i >= len(keypresses):
                            break
                else:
                    keypress_time = kp.key_up - kp.key_down
                    keypress_times.append(apply_mods_to_time(keypress_time,
                                                             replay.mods))
                    kp_i += 1
                ho_i += 1
            else:
                kp_i += 1

    return keypress_times, sliderend_release_times
