#! /usr/bin/python3

# Copyright 2019 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_overlay_widgets.py:
#  Code generation for overlay widgets.  Should be run when the widgets declaration file,
#  overlay_widgets.json, is changed.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.

import json
import os
import sys

OUT_SOURCE_FILE_NAME = 'Overlay_autogen.cpp'
OUT_HEADER_FILE_NAME = 'Overlay_autogen.h'

IN_JSON_FILE_NAME = 'overlay_widgets.json'

OUT_SOURCE_FILE_TEMPLATE = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}.
//
// Copyright 2019 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.
//
// {out_file_name}:
//   Autogenerated overlay widget declarations.

#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/Overlay.h"
#include "libANGLE/OverlayWidgets.h"
#include "libANGLE/Overlay_font_autogen.h"

namespace gl
{{
using namespace overlay;

namespace
{{
int GetFontSize(int fontSize, bool largeFont)
{{
    if (largeFont && fontSize > 0)
    {{
        return fontSize - 1;
    }}
    return fontSize;
}}
}}  // anonymous namespace

void Overlay::initOverlayWidgets()
{{
    const bool kLargeFont = rx::IsAndroid();

    {init_widgets}
}}

}}  // namespace gl

"""

OUT_HEADER_FILE_TEMPLATE = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}.
//
// Copyright 2019 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.
//
// {out_file_name}:
//   Autogenerated overlay widget declarations.

namespace gl
{{
enum class WidgetId
{{
{widget_ids}
    InvalidEnum,
    EnumCount = InvalidEnum,
}};

// We can use this "X" macro to generate multiple code patterns.
#define ANGLE_WIDGET_ID_X(PROC) \
{widget_x_defs}

}}  // namespace gl
"""

WIDGET_INIT_TEMPLATE = u"""{{
const int32_t fontSize = GetFontSize({font_size}, kLargeFont);
const int32_t offsetX = {offset_x};
const int32_t offsetY = {offset_y};
const int32_t width = {width};
const int32_t height = {height};

widget->{subwidget}type          = WidgetType::{type};
widget->{subwidget}fontSize      = fontSize;
widget->{subwidget}coords[0]     = {coord0};
widget->{subwidget}coords[1]     = {coord1};
widget->{subwidget}coords[2]     = {coord2};
widget->{subwidget}coords[3]     = {coord3};
widget->{subwidget}color[0]      = {color_r}f;
widget->{subwidget}color[1]      = {color_g}f;
widget->{subwidget}color[2]      = {color_b}f;
widget->{subwidget}color[3]      = {color_a}f;
widget->{subwidget}matchToWidget = {match_to};
}}
"""

WIDGET_ID_TEMPLATE = """    // {comment}
    {name},
"""


def extract_type_and_constructor(properties):
    constructor = properties['type']
    args_separated = constructor.split('(', 1)
    if len(args_separated) == 1:
        return constructor, constructor

    type_no_constructor = args_separated[0]
    return type_no_constructor, constructor


def get_font_size_constant(properties):
    return 'kFontMip' + properties['font'].capitalize()


def is_graph_type(type):
    return type == 'RunningGraph' or type == 'RunningHistogram'


def is_text_type(type):
    return not is_graph_type(type)


class OverlayWidget:

    def __init__(self, properties, is_graph_description=False):
        if not is_graph_description:
            self.name = properties['name']
        self.type, self.constructor = extract_type_and_constructor(properties)
        self.extract_common(properties)

        if is_graph_type(self.type):
            description_properties = properties['description']
            description_properties['type'] = 'Text'
            self.description = OverlayWidget(description_properties, True)

    def extract_common(self, properties):
        self.color = properties['color']
        self.coords = properties['coords']
        self.match_to = properties.get('match_to', None)
        if is_graph_type(self.type):
            self.bar_width = properties['bar_width']
            self.height = properties['height']
        else:
            self.font = get_font_size_constant(properties)
            self.length = properties['length']

        self.negative_alignment = [False, False]


def get_relative_coord_widget(coord, widgets_so_far):
    if not isinstance(coord, str):
        return None

    coord_split = coord.split('.')
    widget = widgets_so_far[coord_split[0]]
    if len(coord_split) > 3:
        widget = widget.description

    return widget


def parse_relative_coord(coord):

    # The input coordinate (widget.coord[axis]) is either:
    #
    # - a number
    # - other_widget.edge.mode:
    #   * edge is in {left, right} or {top, bottom} based on axis
    #   * mode is in {align, adjacent}
    # - other_widget.desc.edge.mode: this is similar to other_widget.edge.mode, except
    #                                it refers to a graph widget's description widget
    #
    # This function parses the last two possibilities.
    if not isinstance(coord, str):
        return None, None, None

    coord_split = coord.split('.')
    coords_expr = 'mState.mOverlayWidgets[WidgetId::' + coord_split[0] + ']'
    if len(coord_split) > 3:
        assert len(coord_split) == 4 and coord_split[1] == 'desc'
        coords_expr += '->getDescriptionWidget()'
    coords_expr += '->coords'

    edge = coord_split[-2]
    mode = coord_split[-1]

    return coords_expr, edge, mode


def is_negative_coord(coords, axis, widgets_so_far):

    other_widget = get_relative_coord_widget(coords[axis], widgets_so_far)
    if other_widget is not None:
        # We simply need to know if other_widget's coordinate is negative or not.
        return other_widget.negative_alignment[axis]

    return coords[axis] < 0


def set_alignment_flags(overlay_widget, widgets_so_far):
    overlay_widget.negative_alignment[0] = is_negative_coord(overlay_widget.coords, 0,
                                                             widgets_so_far)
    overlay_widget.negative_alignment[1] = is_negative_coord(overlay_widget.coords, 1,
                                                             widgets_so_far)

    if is_graph_type(overlay_widget.type):
        set_alignment_flags(overlay_widget.description, widgets_so_far)


def get_offset_helper(widget, axis, smaller_coord_side):
    # Assume axis is X.  This function returns two values:
    # - An offset where the bounding box is placed at,
    # - Whether this offset is for the left or right edge.
    #
    # The input coordinate (widget.coord[axis]) is either:
    #
    # - a number: in this case, the offset is that number, and its sign
    #             determines whether this refers to the left or right edge of
    #             the bounding box.
    # - other_widget[.desc].edge.mode: this has multiple possibilities:
    #   * edge=left, mode=align: the offset is other_widget[.desc].left, the edge is left.
    #   * edge=left, mode=adjacent: the offset is other_widget[.desc].left, the edge is right.
    #   * edge=right, mode=align: the offset is other_widget[.desc].right, the edge is right.
    #   * edge=right, mode=adjacent: the offset is other_widget[.desc].right, the edge is left.
    #
    # The case for the Y axis is similar, with the edge values being top or bottom.

    coord = widget.coords[axis]

    other_coords_expr, relative_edge, relative_mode = parse_relative_coord(coord)
    if other_coords_expr is None:
        is_left = coord >= 0
        return coord, is_left

    is_left = relative_edge == smaller_coord_side
    is_align = relative_mode == 'align'

    other_widget_coord_index = axis + (0 if is_left else 2)
    offset = other_coords_expr + '[' + str(other_widget_coord_index) + ']'

    return offset, is_left == is_align


def get_offset_x(widget):
    return get_offset_helper(widget, 0, 'left')


def get_offset_y(widget):
    return get_offset_helper(widget, 1, 'top')


def get_bounding_box_coords(offset, width, offset_is_left, is_left_aligned):
    # See comment in generate_widget_init_helper.  This function is implementing the following:
    #
    # -  offset_is_left &&  is_left_aligned: [offset, offset + width]
    # -  offset_is_left && !is_left_aligned: [offset, std::min(offset + width, -1)]
    # - !offset_is_left &&  is_left_aligned: [std::max(1, offset - width), offset]
    # - !offset_is_left && !is_left_aligned: [offset - width, offset]

    coord_left = offset if offset_is_left else (offset + ' - ' + width)
    coord_right = (offset + ' + ' + width) if offset_is_left else offset

    if offset_is_left and not is_left_aligned:
        coord_right = 'std::min(' + coord_right + ', -1)'
    if not offset_is_left and is_left_aligned:
        coord_left = 'std::max(' + coord_left + ', 1)'

    return coord_left, coord_right


def generate_widget_init_helper(widget, is_graph_description=False):
    font_size = '0'

    # Common attributes
    color = [channel / 255.0 for channel in widget.color]
    offset_x, offset_x_is_left = get_offset_x(widget)
    offset_y, offset_y_is_top = get_offset_y(widget)

    if is_text_type(widget.type):
        # Attributes deriven from text properties
        font_size = widget.font
        width = str(widget.length) + ' * (kFontGlyphWidth >> fontSize)'
        height = '(kFontGlyphHeight >> fontSize)'
    else:
        # Attributes deriven from graph properties
        width = str(widget.bar_width) + ' * static_cast<uint32_t>(widget->runningValues.size())'
        height = widget.height

    is_left_aligned = not widget.negative_alignment[0]
    is_top_aligned = not widget.negative_alignment[1]

    # We have offset_x, offset_y, width and height which together determine the bounding box.  If
    # offset_x_is_left, the bounding box X would be in [offset_x, offset_x + width], otherwise it
    # would be in [offset_x - width, offset_x].  Similarly for y.  Since we use negative values to
    # mean aligned to the right side of the screen, we need to make sure that:
    #
    # - if left aligned: offset_x - width is at minimum 1
    # - if right aligned: offset_x + width is at maximum -1
    #
    # We therefore have the following combinations for the X axis:
    #
    # -  offset_x_is_left &&  is_left_aligned: [offset_x, offset_x + width]
    # -  offset_x_is_left && !is_left_aligned: [offset_x, std::min(offset_x + width, -1)]
    # - !offset_x_is_left &&  is_left_aligned: [std::max(1, offset_x - width), offset_x]
    # - !offset_x_is_left && !is_left_aligned: [offset_x - width, offset_x]
    #
    # Similarly for y.
    coord0, coord2 = get_bounding_box_coords('offsetX', 'width', offset_x_is_left, is_left_aligned)
    coord1, coord3 = get_bounding_box_coords('offsetY', 'height', offset_y_is_top, is_top_aligned)

    match_to = 'nullptr' if widget.match_to is None else \
               'mState.mOverlayWidgets[WidgetId::' + widget.match_to + '].get()'

    return WIDGET_INIT_TEMPLATE.format(
        subwidget='description.' if is_graph_description else '',
        offset_x=offset_x,
        offset_y=offset_y,
        width=width,
        height=height,
        type=widget.type,
        font_size=font_size,
        coord0=coord0,
        coord1=coord1,
        coord2=coord2,
        coord3=coord3,
        color_r=color[0],
        color_g=color[1],
        color_b=color[2],
        color_a=color[3],
        match_to=match_to)


def generate_widget_init(widget):
    widget_init = '{\n' + widget.type + ' *widget = new ' + widget.constructor + ';\n'

    widget_init += generate_widget_init_helper(widget)
    widget_init += 'mState.mOverlayWidgets[WidgetId::' + widget.name + '].reset(widget);\n'

    if is_graph_type(widget.type):
        widget_init += generate_widget_init_helper(widget.description, True)

    widget_init += '}\n'

    return widget_init


def main():
    if len(sys.argv) == 2 and sys.argv[1] == 'inputs':
        print(IN_JSON_FILE_NAME)
        return
    if len(sys.argv) == 2 and sys.argv[1] == 'outputs':
        outputs = [
            OUT_SOURCE_FILE_NAME,
            OUT_HEADER_FILE_NAME,
        ]
        print(','.join(outputs))
        return

    with open(IN_JSON_FILE_NAME) as fin:
        layout = json.loads(fin.read())

    widgets = layout['widgets']

    # Read the layouts from the json file and determine alignment of widgets (as they can refer to
    # other widgets.
    overlay_widgets = {}
    for widget_properties in widgets:
        widget = OverlayWidget(widget_properties)
        overlay_widgets[widget.name] = widget
        set_alignment_flags(widget, overlay_widgets)

    # Go over the widgets again and generate initialization code.  Note that we need to iterate over
    # the widgets in order, so we can't use the overlay_widgets dictionary for iteration.
    init_widgets = []
    for widget_properties in widgets:
        init_widgets.append(generate_widget_init(overlay_widgets[widget_properties['name']]))

    with open(OUT_SOURCE_FILE_NAME, 'w') as outfile:
        outfile.write(
            OUT_SOURCE_FILE_TEMPLATE.format(
                script_name=os.path.basename(__file__),
                input_file_name=IN_JSON_FILE_NAME,
                out_file_name=OUT_SOURCE_FILE_NAME,
                init_widgets='\n'.join(init_widgets)))
        outfile.close()

    with open(OUT_HEADER_FILE_NAME, 'w') as outfile:
        widget_ids = [WIDGET_ID_TEMPLATE.format(**widget) for widget in widgets]
        widget_x_defs = ["PROC(" + widget['name'] + ")" for widget in widgets]

        outfile.write(
            OUT_HEADER_FILE_TEMPLATE.format(
                script_name=os.path.basename(__file__),
                input_file_name=IN_JSON_FILE_NAME,
                out_file_name=OUT_SOURCE_FILE_NAME,
                widget_ids=''.join(widget_ids),
                widget_x_defs=' \\\n'.join(widget_x_defs)))
        outfile.close()


if __name__ == '__main__':
    sys.exit(main())
