import re

from npbg.gl.programs import NNScene


def parse_input_string_obsolete(what):
    config = {}
    if '_pr' in what:
        config['draw_points'] = True
        config['splat_mode'] = True
        config['point_size'] = int(what.split('_pr')[-1])
        config['flat_color'] = True
    elif '_p' in what:
        config['draw_points'] = True
        config['splat_mode'] = False
        config['point_size'] = int(what.split('_p')[-1])
        config['flat_color'] = True
    else:
        config['draw_points'] = False
        config['splat_mode'] = False
        config['point_size'] = 1
        config['flat_color'] = False

    if 'colors' in what:
        config['mode'] = NNScene.MODE_COLOR, 0
    elif 'uv' in what:
        m1 = NNScene.UV_TYPE_1D if config['draw_points'] else NNScene.UV_TYPE_2D
        config['mode'] = NNScene.MODE_UV, m1
    elif 'normals' in what:
        nm = what.split('_')[-2] if '_p' in what else what.split('_')[-1]
        m1 = ['g', 'r', 'l', 'd'].index(nm)
        config['mode'] = NNScene.MODE_NORMALS, m1
    elif 'xyz' in what:
        config['mode'] = NNScene.MODE_XYZ, 0

    return config


def parse_input_string(string):
    config = {}
    
    if re.search('^colors', string):
        config['mode'] = NNScene.MODE_COLOR, None
    elif re.search('^uv', string):
        choices = ['uv_1d', 'uv_2d']
        ch = re.findall('|'.join(choices), string)[-1]
        m1 = choices.index(ch)
        config['mode'] = NNScene.MODE_UV, m1
    elif re.search('^normals', string):
        choices = ['normals_m', 'normals_r', 'normals_l', 'normals_d']
        ch = re.findall('|'.join(choices), string)[-1]
        m1 = choices.index(ch)
        config['mode'] = NNScene.MODE_NORMALS, m1
    elif re.search('^xyz', string):
        config['mode'] = NNScene.MODE_XYZ, None
    elif re.search('^depth', string):
        config['mode'] = NNScene.MODE_DEPTH, None
    elif re.search('^labels', string):
        config['mode'] = NNScene.MODE_LABEL, None
    else:
        raise ValueError(string)
        
    res = re.findall('ps[0-9]+|p[0-9]+', string)
    if res:
        res = res[-1]
        config['draw_points'] = True
        config['flat_color'] = True
        config['point_size'] = int(re.search('[0-9]+', res).group())
        config['splat_mode'] = re.search('^ps', res) is not None
    else:
        config['draw_points'] = False
        config['splat_mode'] = False
        config['point_size'] = 1
        config['flat_color'] = False
    
    res = re.findall('ds[0-5]+', string)
    if res:
        res = res[-1]
        config['downscale'] = int(re.search('[0-9]+', res).group())
            

    return config


def generate_input_string(config):
    s = ''
    m0, m1 = config['mode']
    if m0 == NNScene.MODE_COLOR:
        s += 'colors'
    elif m0 == NNScene.MODE_UV:
        s += 'uv'
        if m1 == NNScene.UV_TYPE_1D:
            s += '_1d'
        elif m1 == NNScene.UV_TYPE_2D:
            s += '_2d'
        else:
            raise ValueError
    elif m0 == NNScene.MODE_NORMALS:
        s += 'normals'
        if m1 == NNScene.NORMALS_MODE_MODEL:
            s += '_m'
        elif m1 == NNScene.NORMALS_MODE_REFLECTION:
            s += '_r'
        elif m1 == NNScene.NORMALS_MODE_LOCAL:
            s += '_l'
        elif m1 == NNScene.NORMALS_MODE_DIRECTION:
            s += '_d'
    elif m0 == NNScene.MODE_XYZ:
        s += 'xyz'
    elif m0 == NNScene.MODE_DEPTH:
        s += 'depth'

    if config['draw_points']:
        s += '_p'
        if config['splat_mode']:
            s += 's'
        s += str(config['point_size'])

    if 'downscale' in config:
        s += f"_ds{config['downscale']}"

    return s



def test_generate_parse():
    configs = [
        {
        'draw_points': True,
        'splat_mode': True,
        'point_size': 20,
        'flat_color': True,

        'mode': (NNScene.MODE_UV, NNScene.UV_TYPE_1D)
        },

        {
        'draw_points': True,
        'splat_mode': True,
        'point_size': 20,
        'flat_color': True,

        'mode': (NNScene.MODE_UV, NNScene.UV_TYPE_2D)
        },

        {
        'draw_points': True,
        'splat_mode': False,
        'point_size': 20,
        'flat_color': True,

        'mode': (NNScene.MODE_COLOR, None)
        },

        {
        'draw_points': False,
        'splat_mode': False,
        'point_size': 1,
        'flat_color': False,

        'mode': (NNScene.MODE_NORMALS, NNScene.NORMALS_MODE_REFLECTION)
        },

        {
        'draw_points': False,
        'splat_mode': False,
        'point_size': 1,
        'flat_color': False,

        'mode': (NNScene.MODE_XYZ, None)
        },

        {
        'draw_points': True,
        'splat_mode': False,
        'point_size': 1,
        'flat_color': True,

        'mode': (NNScene.MODE_XYZ, None),

        'downscale': 2
        },
        ]

    def check(config):
        print('config:\n', config)
        s = generate_input_string(config)
        print('string:\n', s)
        c = parse_input_string(s)
        print('generated config:\n', c)
        print('-- OK' if config == c else '-- FAIL')

    for c in configs:
        check(c)


if __name__ == '__main__':
    test_generate_parse()