#!/usr/bin/python

from os import listdir
from os.path import isfile, join

def CamelCase(str):
  return str.replace('_', ' ').title().replace(' ', '')

def WriteEnum(file_name, file_base_name, out, is_binding):
  out.write('/*\n* Generated by python\n* Any changes to this file will be overwritten by the next python run\n*/\n\n')
  out.write('#pragma once\n')
  out.write('\n#include "../../config.h"\n')
  if is_binding:
    out.write('#include "' + file_name.replace('binding.txt', 'type.h') + '"\n')
  out.write('#if 0')
  lines = open('../src/' + file_name).readlines()
  for line in lines:
    enum = line[:-1]
    out.write('\\\n|| (defined(' + enum + '))')
  out.write("""
namespace Ubpa::gl {
\tenum class """)
  out.write(CamelCase(file_base_name) + ' : GLenum {\n')
  for line in lines:
    enum = line[:-1]
    out.write('#ifdef '+enum + '\n')
    out.write('\t\t' + CamelCase(enum[3:]) + ' = ' + enum + ',\n')
    out.write('#endif\n')

  out.write("""\t};
}
#endif

""")

def HandleNormalEnumFile(file_name, file_base_name, out):
  WriteEnum(file_name, file_base_name, out, False)

def HandleBindingEnumFile(file_name, file_base_name, out):
  WriteEnum(file_name, file_base_name, out, True)
  binding_lines = open('../src/' + file_name).readlines()
  target_lines = open('../src/' + file_name.replace('binding', 'type')).readlines()
  out.write('#if 0')
  for line_num in range(0, len(binding_lines)):
    binding_enum = binding_lines[line_num][:-1]
    target_enum = target_lines[line_num][:-1]
    out.write('\\\n|| (defined(' + binding_enum + ') && defined(' + target_enum + '))')
  out.write("""
namespace Ubpa::gl {
""")
  binding = CamelCase(file_base_name)
  target = binding.replace('Binding', 'Type')
  out.write('\tinline ' + binding + ' BindOf(' +
             target + ' type) {\n')
  out.write('\t\tswitch (type) {\n')

  if len(binding_lines) != len(target_lines):
    raise Exception(file_name + ' mismatches ' +
      file_name.replace('binding', 'type') + ' in element size.')
  for line_num in range(0, len(binding_lines)):
    binding_enum = binding_lines[line_num][:-1]
    target_enum = target_lines[line_num][:-1]
    out.write('#if defined(' + binding_enum + ') && defined(' + target_enum + ')\n')
    out.write('\t\tcase ' + target + '::' + CamelCase(target_enum[3:]) + ':\n')
    out.write('\t\t\treturn ' + binding + '::' + CamelCase(binding_enum[3:]) + ';\n')
    out.write('#endif\n')
  out.write('\t\t}\n\t}\n}\n')
  out.write('#endif\n')


file_list = [ f for f in listdir('../src') if isfile(join('../src', f)) ]
enum_file = open('../../../include/UGL/enums.h', 'w')
enum_file.write('#pragma once\n\n#include "detail/enum_boolean_op.h"\n\n')

for file_name in file_list:
  file_base_name = file_name[:-4]
  enum_file.write('#include "detail/enums/' + file_base_name + '.h"\n')
  out = open('../../../include/UGL/detail/enums/' + file_base_name + '.h', 'w')

  if file_name.endswith('_binding.txt'):
    HandleBindingEnumFile(file_name, file_base_name, out)
  elif file_name.endswith('.txt'):
    HandleNormalEnumFile(file_name, file_base_name, out)

  out.close()
