
from . import glyphs

from six import iteritems

def _glyph_function(glyphclass, argnames, docstring, xfields=["x"], yfields=["y"]):

    def func(document_or_plot, *args, **kwargs):
        # Note: We want to reuse the glyph functions by attaching them the Plot
        # class. Imports are here to prevent circular imports.
        from .plotting_helpers import (
            _match_data_params, _update_plot_data_ranges,
            _materialize_colors_and_alpha, _get_legend,
            _make_legend, _get_select_tool
        )
        from .objects import ColumnDataSource, Glyph, Plot, ServerDataSource
        source = kwargs.pop('source', None)
        if isinstance(source, ServerDataSource):
            datasource = ColumnDataSource()
            serversource = source
        elif source is None:
            datasource = ColumnDataSource()
            serversource = None
        else:
            datasource = source
            serversource = None

        legend_name = kwargs.pop("legend", None)

        from .document import Document
        document = None
        plot = None
        if isinstance(document_or_plot, Plot):
            plot = document_or_plot
            # TODO (bev) plot.update(kwargs)
        elif isinstance(document_or_plot, Document):
            document = document_or_plot
            plot = document._get_plot(kwargs)
        else:
            raise ValueError("expected document or plot object for first argument")

        name = kwargs.pop('name', None)
        if name:
            plot._id = name

        select_tool = _get_select_tool(plot)

        # Process the glyph dataspec parameters
        glyph_params = _match_data_params(argnames, glyphclass,
                                          datasource, serversource,
                                          args, _materialize_colors_and_alpha(kwargs))


        x_data_fields = []
        for xx in xfields:
            if not isinstance(glyph_params[xx], dict): continue
            if glyph_params[xx]['units'] == 'data': x_data_fields.append(glyph_params[xx]['field'])
        y_data_fields = []
        for yy in yfields:
            if not isinstance(glyph_params[yy], dict): continue
            if glyph_params[yy]['units'] == 'data': y_data_fields.append(glyph_params[yy]['field'])

        _update_plot_data_ranges(plot, datasource, x_data_fields, y_data_fields)
        kwargs.update(glyph_params)

        glyph_props = glyphclass.properties()
        glyph_kwargs = dict((key, value) for (key, value) in iteritems(kwargs) if key in glyph_props)

        glyph = glyphclass(**glyph_kwargs)

        nonselection_glyph_params = _materialize_colors_and_alpha(kwargs, prefix='nonselection_', default_alpha=0.1)
        nonselection_glyph = glyph.clone()

        nonselection_glyph.fill_color = nonselection_glyph_params['fill_color']
        nonselection_glyph.line_color = nonselection_glyph_params['line_color']

        nonselection_glyph.fill_alpha = nonselection_glyph_params['fill_alpha']
        nonselection_glyph.line_alpha = nonselection_glyph_params['line_alpha']

        glyph_renderer = Glyph(
            data_source=datasource,
            server_data_source=serversource,
            glyph=glyph,
            nonselection_glyph=nonselection_glyph,
            name=name)

        # TODO (bev) hacky, fix up when glyphspecs are simplified/removed
        if 'x_range_name' in kwargs:
            glyph_renderer.x_range_name = kwargs['x_range_name']
        if 'y_range_name' in kwargs:
            glyph_renderer.y_range_name = kwargs['y_range_name']

        if legend_name: