#!/usr/bin/python
# Copyright 2016 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_copy_conversion_table.py:
#  Code generation for ES3 valid copy conversions table format map.

from datetime import date
import sys

sys.path.append('renderer')
import angle_format

template_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// format_map:
//   Determining the sized internal format from a (format,type) pair.
//   Also check es3 format combinations for validity.

#include "angle_gl.h"
#include "common/debug.h"

namespace gl
{{

bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
{{
    switch (textureFormat)
    {{
{texture_format_cases}        default:
            break;
    }}

    return false;
}}

}}  // namespace gl
"""

template_format_case = """        case {texture_format}:
            switch (framebufferFormat)
            {{
{framebuffer_format_cases}                    return true;
                default:
                    break;
            }}
            break;

"""

template_simple_case = """                case {key}:
"""

def parse_texture_format_case(texture_format, framebuffer_formats):
    framebuffer_format_cases = ""
    for framebuffer_format in sorted(framebuffer_formats):
        framebuffer_format_cases += template_simple_case.format(key = framebuffer_format)
    return template_format_case.format(
        texture_format = texture_format, framebuffer_format_cases = framebuffer_format_cases)

data_source_name = 'es3_copy_conversion_formats.json'

json_data = angle_format.load_json(data_source_name)

format_map = {}

for description, data in json_data.iteritems():
    for texture_format, framebuffer_format in data:
        if texture_format not in format_map:
            format_map[texture_format] = []
        format_map[texture_format] += [ framebuffer_format ]

texture_format_cases = ""

for texture_format, framebuffer_formats in sorted(format_map.iteritems()):
    texture_format_cases += parse_texture_format_case(texture_format, framebuffer_formats)

with open('es3_copy_conversion_table_autogen.cpp', 'wt') as out_file:
    output_cpp = template_cpp.format(
        script_name = sys.argv[0],
        data_source_name = data_source_name,
        copyright_year = date.today().year,
        texture_format_cases = texture_format_cases)
    out_file.write(output_cpp)
    out_file.close()
