#! /usr/bin/python

# 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 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_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 'kFontLayer' + 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']
        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 is_negative_coord(coords, axis, widgets_so_far):

    if isinstance(coords[axis], unicode):
        coord_split = coords[axis].split('.')
        # The coordinate is in the form other_widget.edge.mode
        # We simply need to know if other_widget's coordinate is negative or not.
        return widgets_so_far[coord_split[0]].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.edge.mode: this has multiple possibilities:
    #   * edge=left, mode=align: the offset is other_widget.left, the edge is left.
    #   * edge=left, mode=adjacent: the offset is other_widget.left, the edge is right.
    #   * edge=right, mode=align: the offset is other_widget.right, the edge is right.
    #   * edge=right, mode=adjacent: the offset is other_widget.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]
    if not isinstance(coord, unicode):
        is_left = coord >= 0
        return coord, is_left

    coord_split = coord.split('.')

    is_left = coord_split[1] == smaller_coord_side
    is_align = coord_split[2] == 'align'

    other_widget_coords = 'mState.mOverlayWidgets[WidgetId::' + coord_split[0] + ']->coords'
    other_widget_coord_index = axis + (0 if is_left else 2)
    offset = other_widget_coords + '[' + 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) + ' * kFontGlyphWidths[fontSize]'
        height = 'kFontGlyphHeights[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)

    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])


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=__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=__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())
