# Path: diva/converters.py
# @singledispatch
# def convert_to_html(val):
#     # default is to just display the value as a string
#     return '<p>{}</p>'.format(str(val))
# 
# Path: diva/widgets.py
# def widgets_template_data(widgets):
#     """
#     The return value of this func should be the input to the widgetform 
#     macro. This generates a widgets form for the given list of widgets.
#     """
#     widget_data = []
#     for index, widget in enumerate(widgets):
#         # the widget type is the name of its python class
#         # the JS setup func is Reports.Widgets.setupMap[widget_type]
#         widget_type = type(widget).__name__
#         html = widget.generateHTML(index)
#         data = {'type': widget_type, 'html': html}
#         widget_data.append(data)
#     return widget_data
# 
# def validate_widget_form_data(widgets, inputs):
#     try:
#         # validate all of the given widget values in 'widgetValues'
#         if type(inputs) is not list:
#             raise ValueError("inputs must be an array")    
#         if len(inputs) != len(widgets):
#             raise ValueError("the inputs array has an incorrect number of items")
#         for wid, value in zip(widgets, inputs):
#             wid.validate_input(value)
#     except Exception as e:
#         raise ValidationError(str(e))
# 
# def parse_widget_form_data(widgets, form_data):
#     """
#     Given list of widgets and a list of form data, with one item
#     for each widget, return a list of parsed form data
#     """
#     inputs = [wid.parseForm(data) for wid, data in 
#             zip(widgets, form_data) if not should_skip(wid)]
#     return inputs
# 
# class Skip(Widget):
#     """
#     A non-interactive widget that just provides a label/header.
#     Useful for clarifying long widget forms
#     """
#     def __init__(self, description):
#         self.description = description
# 
#     def generateHTML(self, formid):
#         return render_template('label_widget.html', description=self.description)
# 
#     def parseForm(self, form_data):
#         """
#         This widget should be skipped when parsing form data
#         see the should_skip and parse_widget_form_data functions below
#         """
#         pass
# 
#     def validate_input(self, form_data):
#         pass
# 
# def should_skip(widget):
#     """
#     True if should skip this widget when parsing values, false ow
#     """
#     return type(widget).__name__ == 'Skip'   
# 
# Path: diva/utilities.py
# @singledispatch
# def get_utilities_for_value(val):
#     return type_utils.get(type(val), [])    
# 
# Path: diva/dashboard.py
# class Dashboard():
#     # default layout is a vertical list of items
#     def __init__(self, items, layout=None):
#         self.items = items
#         if layout is None:
#             self.layout = [[0, i, 1, 1] for i in range(len(items))]
#         else:
#             self.layout = layout


import inspect
from jsonschema import validate
from collections import OrderedDict
from .converters import convert_to_html
from .widgets import (widgets_template_data, validate_widget_form_data,
        parse_widget_form_data, Skip, should_skip)
from .utilities import get_utilities_for_value
from .dashboard import Dashboard
from .exceptions import *
from flask import Flask, render_template, request, abort, jsonify
        """
        Creates a view that composes the specified views into a single view,
        arranged according to the given layout.

        id_list: list of IDs/short names of the reports to combine
        layout: a list of coordinate lists, in the same format as specified in
        the Dashboard constructor
        """
        # get all reports with matching names
        report_list = [report for report in self.reports if report['id'] in id_list]
        if len(report_list) < len(id_list):
            raise ValueError("one of the given reports was not found: {}".format(id_list))

        # concatenate the widgets of the reports
        # also add labels between the widget groups
        all_widgets = []
        for index, r in enumerate(report_list):
            all_widgets.append(Skip('report {}'.format(index)))
            all_widgets.extend(r['widgets'])

        # register a view that takes the list of all widgets, and gives the 
        # correct arguments to the correct reports
        @self.view(name, all_widgets, short)
        def view_func(*widget_args):
            # regenerate all reports, passing in the values from the relevant widgets
            remaining_args = widget_args
            results = []
            for r in report_list:
                # get the number of widgets that pass their value to the underlying
                # function (that is, the number that shouldn't be skipped)

# Path: diva/converters.py
# @singledispatch
# def convert_to_html(val):
#     # default is to just display the value as a string
#     return '<p>{}</p>'.format(str(val))
# 
# Path: diva/widgets.py
# def widgets_template_data(widgets):
#     """
#     The return value of this func should be the input to the widgetform 
#     macro. This generates a widgets form for the given list of widgets.
#     """
#     widget_data = []
#     for index, widget in enumerate(widgets):
#         # the widget type is the name of its python class
#         # the JS setup func is Reports.Widgets.setupMap[widget_type]
#         widget_type = type(widget).__name__
#         html = widget.generateHTML(index)
#         data = {'type': widget_type, 'html': html}
#         widget_data.append(data)
#     return widget_data
# 
# def validate_widget_form_data(widgets, inputs):
#     try:
#         # validate all of the given widget values in 'widgetValues'
#         if type(inputs) is not list:
#             raise ValueError("inputs must be an array")    
#         if len(inputs) != len(widgets):
#             raise ValueError("the inputs array has an incorrect number of items")
#         for wid, value in zip(widgets, inputs):
#             wid.validate_input(value)
#     except Exception as e:
#         raise ValidationError(str(e))
# 
# def parse_widget_form_data(widgets, form_data):
#     """
#     Given list of widgets and a list of form data, with one item
#     for each widget, return a list of parsed form data
#     """
#     inputs = [wid.parseForm(data) for wid, data in 
#             zip(widgets, form_data) if not should_skip(wid)]
#     return inputs
# 
# class Skip(Widget):
#     """
#     A non-interactive widget that just provides a label/header.
#     Useful for clarifying long widget forms
#     """
#     def __init__(self, description):
#         self.description = description
# 
#     def generateHTML(self, formid):
#         return render_template('label_widget.html', description=self.description)
# 
#     def parseForm(self, form_data):
#         """
#         This widget should be skipped when parsing form data
#         see the should_skip and parse_widget_form_data functions below
#         """
#         pass
# 
#     def validate_input(self, form_data):
#         pass
# 
# def should_skip(widget):
#     """
#     True if should skip this widget when parsing values, false ow
#     """
#     return type(widget).__name__ == 'Skip'   
# 
# Path: diva/utilities.py
# @singledispatch
# def get_utilities_for_value(val):
#     return type_utils.get(type(val), [])    
# 
# Path: diva/dashboard.py
# class Dashboard():
#     # default layout is a vertical list of items
#     def __init__(self, items, layout=None):
#         self.items = items
#         if layout is None:
#             self.layout = [[0, i, 1, 1] for i in range(len(items))]
#         else:
#             self.layout = layout


# Path: diva/reporter.py
import inspect
from jsonschema import validate
from collections import OrderedDict
from .converters import convert_to_html
from .widgets import (widgets_template_data, validate_widget_form_data,
        parse_widget_form_data, Skip, should_skip)
from .utilities import get_utilities_for_value
from .dashboard import Dashboard
from .exceptions import *
from flask import Flask, render_template, request, abort, jsonify

        """
        Creates a view that composes the specified views into a single view,
        arranged according to the given layout.

        id_list: list of IDs/short names of the reports to combine
        layout: a list of coordinate lists, in the same format as specified in
        the Dashboard constructor
        """
        # get all reports with matching names
        report_list = [report for report in self.reports if report['id'] in id_list]
        if len(report_list) < len(id_list):
            raise ValueError("one of the given reports was not found: {}".format(id_list))

        # concatenate the widgets of the reports
        # also add labels between the widget groups
        all_widgets = []
        for index, r in enumerate(report_list):
            all_widgets.append(Skip('report {}'.format(index)))
            all_widgets.extend(r['widgets'])

        # register a view that takes the list of all widgets, and gives the 
        # correct arguments to the correct reports
        @self.view(name, all_widgets, short)
        def view_func(*widget_args):
            # regenerate all reports, passing in the values from the relevant widgets
            remaining_args = widget_args
            results = []
            for r in report_list:
                # get the number of widgets that pass their value to the underlying
                # function (that is, the number that shouldn't be skipped)

                active_widgets = [w for w in r['widgets'] if not should_skip(w)]