# Here starts the boiler plate
from zope.interface import implements   # <- this is needed here to form the PlotImage component
from zope.component import getGlobalSiteManager, adapts   # <- Only needed for the extension afterwards
gsm = getGlobalSiteManager()                              # <- Only needed for the extension afterwards
# End of Boiler plate

# Import of the sub components.
from graph_ZCA.components import BaseComponent, Image, Axis, ViewBox

# Only needed for the extension afterwards.
from graph_ZCA.interfaces import IAxis, IViewBox, IBaseComponent
from graph_ZCA.components import TickLabelComponent, AxisComponent


# Set up a new interface for the component PlotImage. Here usually properties, functions and other exposed items
# of a PlotImage instance would be documented and registered to the framework. Since the only function render is
# already documented for IBaseComponent nothing has to be done here.
class IPlotImage(IBaseComponent):
    """
    Component to plot a 2d graph of a given image
    """

# Here the component itself is constructed. The component inherits from a simple BaseComponent without much importance.
# The only crucial requirement is that every component knows its parent component as self.parent, which is the first
# parameter to the constructor. The top most component has a parent of NONE.
class PlotImage( BaseComponent):
    """
    Makes a 2D plot for an image
    """
    implements(IPlotImage)   # here the interface specified above is used.

    def __init__(self, parent):
        super(PlotImage, self).__init__(parent)   # tribute to the super class

        self.vb = ViewBox(self)()   # make a ViewBox. Please notice the double Braces. These are neccessary for the framework.
                                    # In fact here in no instance generated but a factory. And with the second brace
                                    # the factory produces the instance.
                                    # The PlotImage "self" is assigned as parent for the ViewBox

        x_axis = Axis(self.vb)()    # Same pattern here
                                    # The axis are assigned to the viewbox
        x_axis.orientation='bottom'
        x_axis.start=0
        x_axis.end=8

        y_axis = Axis(self.vb)()    # and here
        y_axis.orientation='left'
        y_axis.start=-5
        y_axis.end=3


        self.vb.addItem( x_axis )   # Finally the axis are given to the viewbox. This step may be not necessary and
                                    # may be done automatically while assigning the parent to the axis.
        self.vb.addItem( y_axis )

    def render(self):               # In this prototype code every component optains a render method that is used to generate
                                    # some simple output
        return self.vb.render()


# # The following statements can be uncommented to illustrate how to swap classes.
# #
# # This example shows how to swap all Axis components which parents are a ViewBoxes to be of class NewAxisComponent
# class NewAxisComponent(AxisComponent):
#      adapts(IViewBox)
#
# gsm.registerAdapter(NewAxisComponent)
#
# # This example shows how to exchange the TickLabelComponent for all Axis
# class NewTickLabelComponent(TickLabelComponent):
#     adapts(IAxis)
#
#     def render(self):
#         return " ".join([ "q%i" % i for i in range(self.axis.start, self.axis.end)])
#
# gsm.registerAdapter(NewTickLabelComponent)


image_data = [1,2,3,4]

plot =  PlotImage( None)
image = Image(plot.vb)(image_data)
plot.vb.addItem(image)

print( plot.render())

