Add axis line.

Add axis line.

Timeline axis in CoffeeScript
=============================

Introduction and description
----------------------------

This demo is aimed at exploring possibilities of visualizing time axis.  This especially applies to situations where time axis is meant to be used in interactive plotting, being able to change from very short time intervals to very long time intervals.

Main points of usability of the timeline are:
 * Area that the timeline takes (ideally, as little as possible).
 * Clarity and readability (ideally text/info should be concise and distinctive).
 * How much information is showed (ideally, as much as current zoom level and resolution can afford).
 * Should be easily navigable (should work also for visually impaired).
 * Should be interactive (ideally react according to its representation).

Test cases
----------

### Visual test cases

 1. All time labels and ticks should correspond to their times
 2. Daylight-saving time should be displayed correctly
 3. Leap seconds should be displayed properly
 4. Every interval type should be displayed properly
   1. year
   2. month
   3. week
   4. day
   5. hour
   6. minute
   7. second
   8. millisecond
 5. Check that lines and text are sharp
 6. There should be no intersection of features

### Unit test cases

To be done:
 * Labels should not intersect with each other
 * There should be at least one label (or no?)
 * Label should be in range if its coordinates are in viewport
 * Check for daylight-saving time
 * Check for daylight-saving time table for several historical intervals
 * Check for leap seconds

Development concerns
--------------------

### Readability

The following things should be thought of before making a final version:
 * DPI should be taken into account.  It should work fine on any DPI display.
 * Every element should be separated from others.
    * Visual elements should not intersect with each other.
    * Visual elements such as labels and ticks should be at some good distance to each other.
 * It is a good idea to alternate colors of intervals.
    * Use two colors.
    * They should differ for visually impaired.
    * And should be suitable for grey-color display.
    * Thus, they should differ in brightness at least.
 * Continuos change (opposed to discrete) between scales (that is zoom levels).
    * Makes it possible to animate without jumps between representation levels, keeping viewer connection to details.
    * Adds more information to viewer.  A question is how to keep this simple enough and not bloated with information and graphics.

### Portability

To make it more flexible to render (to canvas, svg, vega, anything else), we should have an intermediate object as output of axis formatting, which could be rendered after withe a chosen rendeder.

Library functions
-----------------

### The __TimelineMaker__ class

Since formatting and rendering of timeline involves a lot of calculations, it is divided in several functions, and they are combined in the __TimelineMaker__ class.  The __options__ parameter will be a dictionary with values that are needed for formatting the timeline.

    class TimelineMaker
      constructor: (@options) ->

The two functions that are intended to be called are __formatTimeAxis()__, which formats time axis into a dictionary that describes the look of axis, and one of the __renderTo...__ functions that render that data dictionary to a desired context.

#### The __formatTimeAxis()__ function

A function that formats time axis into an intermediate format.  It has two parameters, __interval__ (a dictionary with __start__ and __end__ values, each of Date type) and corresponding to that interval __width__ of a viewport.  It returns a formatted time axis object.  This object is a collection of features with their coordinates in a viewport (the top left point of the viewport is (0,0), the top-right is (0, width)).

      formatTimeAxis: (interval, width) ->
        {@start, end} = interval
        @intervalLength = end - @start
        @width = width

We can put on axis ticks and labels, and also colour areas between them.  They correspond to a set of time points.  Labels could correspond to time points or to time intervals between these points.

Ticks should correspond to _edge points_ of time, a point of time between two days (00-00), two years, months, weeks, or a sharp time point, having integer number of hours, or minutes, or seconds.  In general, while moving from bigger to smaller time interval types, every interval type has to be in integer amount, until  some point.  For example (10 years, 2 months, 3 days) from Epoch and remainder which is less than one day.  That means whe should have a parameter that corresponds to the smallest time interval that has to be integral.  We call this parameter _options.intervalType_.  We also need a number of this intervals between each tick.  This parameter will be __options.intervalMultiplier__.  There is one exception though:  in case of weeks there is no previous integral interval.  So there are two cases:  week and (year, month, day, hour, minute, second, millisecond).

So we need to build a list of time points that correspond to a given time interval.  We will put such code in a special function, __findPointList()__.

        pointList = @findPointList @start, end

Now, when we have found the list of time points, we need to construct a dictionary with graphical element properties.  To transform time value into a coordinate we use the __timeToCoord()__ function.  We start with ticks.  Each tick is a line.  The @options.tickLength parameter is a base length of a tick.  We assume that (y = 0) is a baseline and tick length is from baseline to `@options.tickLength` down and `@options.tickLength/5` up.

We should probably change ticks dictionary to lines dictionary instead, so we can add other types of lines, like baseline.  It could be better also to move all constants to options and make ticks drawing more flexible.

        ticks = for timePoint in pointList
          {
            x1: @timeToCoord timePoint
            x2: @timeToCoord timePoint
            y1: -@options.tickLength / 5
            y2: @options.tickLength
          }

We also add axis.

        axisLine = {
          x1: 0
          x2: @width
          y1: 0
          y2: 0
        }

Now we add text labels too.

Here we also need to improve formatting, now it's just a quick fix to display text.  Text should be formatted without problems on any display and resolution and shouldn't intersect ticks when it has reasonable font size.

        textLabels = for timePoint in pointList
          {
            x: @timeToCoord timePoint
            y: @options.tickLength * 1.2
            text: switch @options.intervalType
              when 'year' then timePoint.getFullYear().toString()
              when 'month' then timePoint.getMonth().toString()
              when 'week', 'day' then timePoint.getDate().toString()
              when 'hour' then timePoint.getHours().toString()
              when 'minute' then timePoint.getMinutes().toString()
              when 'second' then timePoint.getSeconds().toString()
              when 'millisecond' then timePoint.getMilliseconds().toString()
          }

Now we combine all elements into a one dictionary and return it.

        {
          lines: ticks.concat axisLine
          textLabels
        }

#### The __findPointList()__ function

This function returns a list of points that are needed to be calculated for a (__start__, __end__) interval.

      findPointList: (start, end) ->

Since we could need labels between time points, we need time points inside the interval (non-inclusive) and one point on left and right side.  We can build the point list by finding the leftmost _edge point_ which is strictly less than the __start__ of the interval.  We move code that does that to the __findLeftTime()__.

        timePoint = @findLeftTime start

Then, we populate the list in by incrementing points until the we reach right end of the interval, using __findNextPoint()__ function.

        pointList = [timePoint]
        until timePoint > end
          timePoint = @findNextPoint timePoint
          pointList.push timePoint
        pointList

#### The __findLeftTime()__ function

The __findLeftTime()__ function calculates the rightmost point of time for current __options.intervalType__ such that it is not inside the given __interval__ (excluding beginning).  The __options.intervalType__ could be one of the following:
 * 'year'
 * 'month'
 * 'week'
 * 'day'
 * 'hour'
 * 'minute'
 * 'second'
 * 'millisecond'
Another option, __options.intervalMultiplier__, says how many of such intervals are between two time points.  It should be an integer value.  For years and months we truncate them to the desired value, while for days and weeks we will count from a fixed origin day near Epoch (Monday 5 january 1970), so that any day intervals are independent from underlying months and years.  That also means that in case of months the __options.intervalMultiplier__ should be equal to 1, 2, 3, 4 or 6 to be displayed correctly.  To calculate number of days or weeks (reduced to 7 calculation for 7 days) from origin day we use binary subtracting, starting from huge multiplier equal to 1048576 (roughly 2800/11200 years), going down to base multiplier equal to 1.  For interval types smaller or equal than hours we use the __findNextPoint()__ function by incrementing local origin (the interval type and everything smaller is reset to 0).  This is done to avoid problems with daylight-saving and similar things.  In __findNextPoint()__ we make sure that edge points are consistent while using different values of __start__.

      findLeftTime: (start) ->
        leftTime = new Date start.getTime()
        switch @options.intervalType
          when 'year'
            newYear = start.getFullYear() - start.getFullYear() % @options.intervalMultiplier
            leftTime.setFullYear newYear, 0, 1
            leftTime.setHours 0, 0, 0, 0
          when 'month'
            newMonth = start.getMonth() - start.getMonth() % @options.intervalMultiplier
            leftTime.setMonth newMonth, 1
            leftTime.setHours 0, 0, 0, 0
          when 'week', 'day'
            leftTime.setFullYear 1970, 0, 5
            leftTime.setHours 0, 0, 0, 0
            delta = 1048576
            intervalMultiplier = @options.intervalMultiplier
            if @options.intervalType is 'week'
              intervalMultiplier *= 7
            while delta >= 1
              nextTime = new Date leftTime.getFullYear(),
                leftTime.getMonth()
                leftTime.getDate() + delta*intervalMultiplier
                leftTime.getHours()
                leftTime.getMinutes()
                leftTime.getSeconds()
                leftTime.getMilliseconds()
              delta /= 2
              leftTime = nextTime if nextTime <= start
          when 'hour'
            leftTime.setHours 0, 0, 0, 0
            while leftTime < start
              nextTime = @findNextPoint leftTime
              leftTime = nextTime if nextTime <= start
          when 'minute'
            newMinutes = start.getMinutes() - start.getMinutes() % @options.intervalMultiplier
            leftTime.setMinutes newMinutes, 0, 0
          when 'second'
            leftTime.setSeconds start.getSeconds(), 0
            while leftTime < start
              nextTime = @findNextPoint leftTime
              leftTime = nextTime if nextTime <= start
          when 'millisecond'
            newMilliseconds = start.getMilliseconds() - start.getMilliseconds() % @options.intervalMultiplier
            leftTime.setMilliseconds newMilliseconds
        leftTime

There is a code repetition in the switch statement above.  One can think of a good way to improve this part of code.

### The __findNextPoint()__ function

This function calculates next edge time point for a current options assuming __timePoint__ argument is an edge time point.  We take care of daylight-saving time and leap seconds here, assuming that at most one hour/minute/second/millisecond is added or subtracted.  Also we assume that subtraction is not happening at time with 0 value, that is something like 00 -> 23 is not happening.

In current implementation we cope with daylight-saving time by adding hours in UTC to date and then checking how the value changes in local time and fixing by one hour if needed.  The same for leap seconds.

      findNextPoint: (timePoint) ->
        nextTime = new Date timePoint.getTime()
        switch @options.intervalType
          when 'year'
            nextTime.setFullYear (timePoint.getFullYear() + @options.intervalMultiplier)
          when 'month'
            nextTime.setMonth (timePoint.getMonth() + @options.intervalMultiplier)
          when 'week'
            nextTime.setDate (timePoint.getDate() + 7*@options.intervalMultiplier)
          when 'day'
            nextTime.setDate (timePoint.getDate() + @options.intervalMultiplier)
          when 'hour'
            nextTime.setUTCHours (timePoint.getUTCHours() + @options.intervalMultiplier)
            hours = nextTime.getHours()
            if hours % @options.intervalMultiplier isnt 0
              if (hours+1) % @options.intervalMultiplier is 0
                nextTime.setUTCHours (nextTime.getUTCHours() + 1)
              else
                nextTime.setUTCHours (nextTime.getUTCHours() - 1)
          when 'minute'
            nextTime.setMinutes (timePoint.getMinutes() + @options.intervalMultiplier)
          when 'second'
            nextTime.setUTCSeconds (timePoint.getUTCSeconds() + @options.intervalMultiplier)
            seconds = nextTime.getSeconds()
            if seconds % @options.intervalMultiplier isnt 0
              if (seconds+1) % @options.intervalMultiplier is 0
                nextTime.setUTCSeconds (nextTime.getUTCSeconds() + 1)
              else
                nextTime.setUTCSeconds (nextTime.getUTCSeconds() - 1)
          when 'millisecond'
            nextTime.setUTCMilliseconds (timePoint.getUTCMilliseconds() + @options.intervalMultiplier)
        nextTime

#### The __timeToCoord()__ function

To get coordinate of time point we use `@intervalLength` that we stored in `formatTimeAxis()`, which is equal to the number of milliseconds between `end` and `start` of the interval.  We use it to calculate pixe/time ratio, equal to `@width / @intervalLength`.

      timeToCoord: (time) ->
        timeFromStart = time - @start
        coordinate = timeFromStart * @width / @intervalLength

#### The __renderToCanvas()__ function

This function renders formatted time axis to html canvas.
 * `axisData` is formatted data (that we get by calling any of the `format...()` functions)
 * `canvas` is a html canvas object on which axis is drawn
 * `left` and `top` are x- and y-coordinates of the canvas that correspond to the (0, 0) point of the axis viewport

      renderToCanvas: (axisData, canvas, left, top) ->

In the beginning we do just regular initialization of context and its properties.  We also wrap our drawing code into `save()` and `restore()` to not alter context properties globally.

        context = canvas.getContext '2d'
        context.save()
        context.strokeStyle = '#000000'
        context.fillStyle = '#000000'
        context.lineWidth = 1
        context.font = 'normal 12px sans-serif'
        context.textAlign = 'center'
        context.textBaseline = 'top'

To all drawing functions we pass coordinates altered by `roundForCanvas()` function, which rounds values in such a way that lines are more sharp.

        for line in axisData.lines
          x1 = left + line.x1
          x2 = left + line.x2
          y1 = top + line.y1
          y2 = top + line.y2
          context.moveTo @roundForCanvas(x1), @roundForCanvas(y1)
          context.lineTo @roundForCanvas(x2), @roundForCanvas(y2)
        context.stroke()

        for textLabel in axisData.textLabels
          x = left + textLabel.x
          y = top + textLabel.y
          context.fillText textLabel.text, x, y

        context.restore()

#### The `roundForCanvas()` function

This function may be used to avoud aliasing of lines, especially on low-resolution displays.  It rounds coordinate to middle-pixel values, which are .5 in case of html canvas.

      roundForCanvas: (coord) ->
        0.5 + Math.round(coord-0.5)

Library tests
-------------

Examples
--------

This simple code displays time axis when html page is loaded, in `timeline` canvas element.

    makeDemo = ->
      canvas = document.getElementById 'timeline'
      context = canvas.getContext '2d'
      context.fillStyle = '#77FFBB'
      context.fillRect(0, 0, canvas.clientWidth, canvas.clientHeight)
      context.stroke()
      timelineMaker = new TimelineMaker {tickLength: 25, intervalType: 'day', intervalMultiplier: 1}
      start = new Date('2015-06-15T00:00:00')
      end = new Date('2015-07-13T15:23:49')
      axisData = timelineMaker.formatTimeAxis {start, end}, canvas.width
      timelineMaker.renderToCanvas axisData, canvas, 0, 15

    window.onload = makeDemo

Timeline axis in CoffeeScript
=============================

Introduction and description
----------------------------

This demo is aimed at exploring possibilities of visualizing time axis.  This especially applies to situations where time axis is meant to be used in interactive plotting, being able to change from very short time intervals to very long time intervals.

Main points of usability of the timeline are:
 * Area that the timeline takes (ideally, as little as possible).
 * Clarity and readability (ideally text/info should be concise and distinctive).
 * How much information is showed (ideally, as much as current zoom level and resolution can afford).
 * Should be easily navigable (should work also for visually impaired).
 * Should be interactive (ideally react according to its representation).

Test cases
----------

### Visual test cases

 1. All time labels and ticks should correspond to their times
 2. Daylight-saving time should be displayed correctly
 3. Leap seconds should be displayed properly
 4. Every interval type should be displayed properly
   1. year
   2. month
   3. week
   4. day
   5. hour
   6. minute
   7. second
   8. millisecond
 5. Check that lines and text are sharp
 6. There should be no intersection of features

### Unit test cases

To be done:
 * Labels should not intersect with each other
 * There should be at least one label (or no?)
 * Label should be in range if its coordinates are in viewport
 * Check for daylight-saving time
 * Check for daylight-saving time table for several historical intervals
 * Check for leap seconds

Development concerns
--------------------

### Readability

The following things should be thought of before making a final version:
 * DPI should be taken into account.  It should work fine on any DPI display.
 * Every element should be separated from others.
    * Visual elements should not intersect with each other.
    * Visual elements such as labels and ticks should be at some good distance to each other.
 * It is a good idea to alternate colors of intervals.
    * Use two colors.
    * They should differ for visually impaired.
    * And should be suitable for grey-color display.
    * Thus, they should differ in brightness at least.
 * Continuos change (opposed to discrete) between scales (that is zoom levels).
    * Makes it possible to animate without jumps between representation levels, keeping viewer connection to details.
    * Adds more information to viewer.  A question is how to keep this simple enough and not bloated with information and graphics.

### Portability

To make it more flexible to render (to canvas, svg, vega, anything else), we should have an intermediate object as output of axis formatting, which could be rendered after withe a chosen rendeder.

Library functions
-----------------

### The __TimelineMaker__ class

Since formatting and rendering of timeline involves a lot of calculations, it is divided in several functions, and they are combined in the __TimelineMaker__ class.  The __options__ parameter will be a dictionary with values that are needed for formatting the timeline.

    class TimelineMaker
      constructor: (@options) ->

The two functions that are intended to be called are __formatTimeAxis()__, which formats time axis into a dictionary that describes the look of axis, and one of the __renderTo...__ functions that render that data dictionary to a desired context.

#### The __formatTimeAxis()__ function

A function that formats time axis into an intermediate format.  It has two parameters, __interval__ (a dictionary with __start__ and __end__ values, each of Date type) and corresponding to that interval __width__ of a viewport.  It returns a formatted time axis object.  This object is a collection of features with their coordinates in a viewport (the top left point of the viewport is (0,0), the top-right is (0, width)).

      formatTimeAxis: (interval, width) ->
        {@start, end} = interval
        @intervalLength = end - @start
        @width = width

We can put on axis ticks and labels, and also colour areas between them.  They correspond to a set of time points.  Labels could correspond to time points or to time intervals between these points.

Ticks should correspond to _edge points_ of time, a point of time between two days (00-00), two years, months, weeks, or a sharp time point, having integer number of hours, or minutes, or seconds.  In general, while moving from bigger to smaller time interval types, every interval type has to be in integer amount, until  some point.  For example (10 years, 2 months, 3 days) from Epoch and remainder which is less than one day.  That means whe should have a parameter that corresponds to the smallest time interval that has to be integral.  We call this parameter _options.intervalType_.  We also need a number of this intervals between each tick.  This parameter will be __options.intervalMultiplier__.  There is one exception though:  in case of weeks there is no previous integral interval.  So there are two cases:  week and (year, month, day, hour, minute, second, millisecond).

So we need to build a list of time points that correspond to a given time interval.  We will put such code in a special function, __findPointList()__.

        pointList = @findPointList @start, end

Now, when we have found the list of time points, we need to construct a dictionary with graphical element properties.  To transform time value into a coordinate we use the __timeToCoord()__ function.  We start with ticks.  Each tick is a line.  The @options.tickLength parameter is a base length of a tick.  We assume that (y = 0) is a baseline and tick length is from baseline to `@options.tickLength` down and `@options.tickLength/5` up.

We should probably change ticks dictionary to lines dictionary instead, so we can add other types of lines, like baseline.  It could be better also to move all constants to options and make ticks drawing more flexible.

        ticks = for timePoint in pointList
          {
            x1: @timeToCoord timePoint
            x2: @timeToCoord timePoint
            y1: -@options.tickLength / 5
            y2: @options.tickLength
          }

Now we add text labels too.

Here we also need to improve formatting, now it's just a quick fix to display text.  Text should be formatted without problems on any display and resolution and shouldn't intersect ticks when it has reasonable font size.

        textLabels = for timePoint in pointList
          {
            x: @timeToCoord timePoint
            y: @options.tickLength * 1.2
            text: switch @options.intervalType
              when 'year' then timePoint.getFullYear().toString()
              when 'month' then timePoint.getMonth().toString()
              when 'week', 'day' then timePoint.getDate().toString()
              when 'hour' then timePoint.getHours().toString()
              when 'minute' then timePoint.getMinutes().toString()
              when 'second' then timePoint.getSeconds().toString()
              when 'millisecond' then timePoint.getMilliseconds().toString()
          }

Now we combine all elements into a one dictionary and return it.

        {lines: ticks, textLabels}

#### The __findPointList()__ function

This function returns a list of points that are needed to be calculated for a (__start__, __end__) interval.

      findPointList: (start, end) ->

Since we could need labels between time points, we need time points inside the interval (non-inclusive) and one point on left and right side.  We can build the point list by finding the leftmost _edge point_ which is strictly less than the __start__ of the interval.  We move code that does that to the __findLeftTime()__.

        timePoint = @findLeftTime start

Then, we populate the list in by incrementing points until the we reach right end of the interval, using __findNextPoint()__ function.

        pointList = [timePoint]
        until timePoint > end
          timePoint = @findNextPoint timePoint
          pointList.push timePoint
        pointList

#### The __findLeftTime()__ function

The __findLeftTime()__ function calculates the rightmost point of time for current __options.intervalType__ such that it is not inside the given __interval__ (excluding beginning).  The __options.intervalType__ could be one of the following:
 * 'year'
 * 'month'
 * 'week'
 * 'day'
 * 'hour'
 * 'minute'
 * 'second'
 * 'millisecond'
Another option, __options.intervalMultiplier__, says how many of such intervals are between two time points.  It should be an integer value.  For years and months we truncate them to the desired value, while for days and weeks we will count from a fixed origin day near Epoch (Monday 5 january 1970), so that any day intervals are independent from underlying months and years.  That also means that in case of months the __options.intervalMultiplier__ should be equal to 1, 2, 3, 4 or 6 to be displayed correctly.  To calculate number of days or weeks (reduced to 7 calculation for 7 days) from origin day we use binary subtracting, starting from huge multiplier equal to 1048576 (roughly 2800/11200 years), going down to base multiplier equal to 1.  For interval types smaller or equal than hours we use the __findNextPoint()__ function by incrementing local origin (the interval type and everything smaller is reset to 0).  This is done to avoid problems with daylight-saving and similar things.  In __findNextPoint()__ we make sure that edge points are consistent while using different values of __start__.

      findLeftTime: (start) ->
        leftTime = new Date start.getTime()
        switch @options.intervalType
          when 'year'
            newYear = start.getFullYear() - start.getFullYear() % @options.intervalMultiplier
            leftTime.setFullYear newYear, 0, 1
            leftTime.setHours 0, 0, 0, 0
          when 'month'
            newMonth = start.getMonth() - start.getMonth() % @options.intervalMultiplier
            leftTime.setMonth newMonth, 1
            leftTime.setHours 0, 0, 0, 0
          when 'week', 'day'
            leftTime.setFullYear 1970, 0, 5
            leftTime.setHours 0, 0, 0, 0
            delta = 1048576
            intervalMultiplier = @options.intervalMultiplier
            if @options.intervalType is 'week'
              intervalMultiplier *= 7
            while delta >= 1
              nextTime = new Date leftTime.getFullYear(),
                leftTime.getMonth()
                leftTime.getDate() + delta*intervalMultiplier
                leftTime.getHours()
                leftTime.getMinutes()
                leftTime.getSeconds()
                leftTime.getMilliseconds()
              delta /= 2
              leftTime = nextTime if nextTime <= start
          when 'hour'
            leftTime.setHours 0, 0, 0, 0
            while leftTime < start
              nextTime = @findNextPoint leftTime
              leftTime = nextTime if nextTime <= start
          when 'minute'
            newMinutes = start.getMinutes() - start.getMinutes() % @options.intervalMultiplier
            leftTime.setMinutes newMinutes, 0, 0
          when 'second'
            leftTime.setSeconds start.getSeconds(), 0
            while leftTime < start
              nextTime = @findNextPoint leftTime
              leftTime = nextTime if nextTime <= start
          when 'millisecond'
            newMilliseconds = start.getMilliseconds() - start.getMilliseconds() % @options.intervalMultiplier
            leftTime.setMilliseconds newMilliseconds
        leftTime

There is a code repetition in the switch statement above.  One can think of a good way to improve this part of code.

### The __findNextPoint()__ function

This function calculates next edge time point for a current options assuming __timePoint__ argument is an edge time point.  We take care of daylight-saving time and leap seconds here, assuming that at most one hour/minute/second/millisecond is added or subtracted.  Also we assume that subtraction is not happening at time with 0 value, that is something like 00 -> 23 is not happening.

In current implementation we cope with daylight-saving time by adding hours in UTC to date and then checking how the value changes in local time and fixing by one hour if needed.  The same for leap seconds.

      findNextPoint: (timePoint) ->
        nextTime = new Date timePoint.getTime()
        switch @options.intervalType
          when 'year'
            nextTime.setFullYear (timePoint.getFullYear() + @options.intervalMultiplier)
          when 'month'
            nextTime.setMonth (timePoint.getMonth() + @options.intervalMultiplier)
          when 'week'
            nextTime.setDate (timePoint.getDate() + 7*@options.intervalMultiplier)
          when 'day'
            nextTime.setDate (timePoint.getDate() + @options.intervalMultiplier)
          when 'hour'
            nextTime.setUTCHours (timePoint.getUTCHours() + @options.intervalMultiplier)
            hours = nextTime.getHours()
            if hours % @options.intervalMultiplier isnt 0
              if (hours+1) % @options.intervalMultiplier is 0
                nextTime.setUTCHours (nextTime.getUTCHours() + 1)
              else
                nextTime.setUTCHours (nextTime.getUTCHours() - 1)
          when 'minute'
            nextTime.setMinutes (timePoint.getMinutes() + @options.intervalMultiplier)
          when 'second'
            nextTime.setUTCSeconds (timePoint.getUTCSeconds() + @options.intervalMultiplier)
            seconds = nextTime.getSeconds()
            if seconds % @options.intervalMultiplier isnt 0
              if (seconds+1) % @options.intervalMultiplier is 0
                nextTime.setUTCSeconds (nextTime.getUTCSeconds() + 1)
              else
                nextTime.setUTCSeconds (nextTime.getUTCSeconds() - 1)
          when 'millisecond'
            nextTime.setUTCMilliseconds (timePoint.getUTCMilliseconds() + @options.intervalMultiplier)
        nextTime

#### The __timeToCoord()__ function

To get coordinate of time point we use `@intervalLength` that we stored in `formatTimeAxis()`, which is equal to the number of milliseconds between `end` and `start` of the interval.  We use it to calculate pixe/time ratio, equal to `@width / @intervalLength`.

      timeToCoord: (time) ->
        timeFromStart = time - @start
        coordinate = timeFromStart * @width / @intervalLength

#### The __renderToCanvas()__ function

This function renders formatted time axis to html canvas.
 * `axisData` is formatted data (that we get by calling any of the `format...()` functions)
 * `canvas` is a html canvas object on which axis is drawn
 * `left` and `top` are x- and y-coordinates of the canvas that correspond to the (0, 0) point of the axis viewport

      renderToCanvas: (axisData, canvas, left, top) ->

In the beginning we do just regular initialization of context and its properties.  We also wrap our drawing code into `save()` and `restore()` to not alter context properties globally.

        context = canvas.getContext '2d'
        context.save()
        context.strokeStyle = '#000000'
        context.fillStyle = '#000000'
        context.lineWidth = 1
        context.font = 'normal 12px sans-serif'
        context.textAlign = 'center'
        context.textBaseline = 'top'

To all drawing functions we pass coordinates altered by `roundForCanvas()` function, which rounds values in such a way that lines are more sharp.

        for line in axisData.lines
          x1 = left + line.x1
          x2 = left + line.x2
          y1 = top + line.y1
          y2 = top + line.y2
          context.moveTo @roundForCanvas(x1), @roundForCanvas(y1)
          context.lineTo @roundForCanvas(x2), @roundForCanvas(y2)
        context.stroke()

        for textLabel in axisData.textLabels
          x = left + textLabel.x
          y = top + textLabel.y
          context.fillText textLabel.text, x, y

        context.restore()

#### The `roundForCanvas()` function

This function may be used to avoud aliasing of lines, especially on low-resolution displays.  It rounds coordinate to middle-pixel values, which are .5 in case of html canvas.

      roundForCanvas: (coord) ->
        0.5 + Math.round(coord-0.5)

Library tests
-------------

Examples
--------

This simple code displays time axis when html page is loaded, in `timeline` canvas element.

    makeDemo = ->
      canvas = document.getElementById 'timeline'
      context = canvas.getContext '2d'
      context.fillStyle = '#77FFBB'
      context.fillRect(0, 0, canvas.clientWidth, canvas.clientHeight)
      context.stroke()
      timelineMaker = new TimelineMaker {tickLength: 25, intervalType: 'day', intervalMultiplier: 1}
      start = new Date('2015-06-15T00:00:00')
      end = new Date('2015-07-13T15:23:49')
      axisData = timelineMaker.formatTimeAxis {start, end}, canvas.width
      timelineMaker.renderToCanvas axisData, canvas, 0, 15

    window.onload = makeDemo


Some refactoring, and a whole lot more error handling/reporting

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    SKIP_WRAP = [
      'constructor'
      'initialize'
      'details'
      'fire'
      'warn'
      'listen'
      'set'
      'runtime_exception'
    ]

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      WRAPPED[cls] = [ ] unless WRAPPED[cls]?

      WRAPPED[cls].indexOf(method) < 0

    determine_local = (token) ->
      project_local = false
      node_local    = false
      name          = token.substring 1, token.length

      if token[0] == '.'
        project_local = true
      else if token[0] == '~'
        node_local = true
      else
        name = token

      [project_local, node_local, name]

    parse_name_and_local = (tokens) ->
      [project_local, node_local, name] = determine_local tokens[0].trim()

      if tokens.length == 2
        alias = tokens[1].trim()
      else if tokens.length == 1
        alias = name
      else
        return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

      [project_local, node_local, name, alias]

    parse_alias_and_parent = (token) ->
      t = token.split '->'

      if t[0].indexOf('#') > -1
        r      = t[0].split '#'
        parent = r[0].trim()
        t[0]   = r[1]

      [parent, t]

    extract_properties = (token) ->
      [parent, t] = parse_alias_and_parent token
      [project_local, node_local, name, alias] = parse_name_and_local t

      [project_local, node_local, name, alias, parent]

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        [project_local, node_local, name, alias, parent] = extract_properties tokens[0]

        if tokens.length == 2
          initializer = tokens[1].trim()
          toks        = initializer.split ':'
          initializer = toks[0].trim()

          if toks.length == 2
            prerequisites = toks[1].split(',').map (p) => p.trim()
          else if toks.length > 2
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length > 2
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || name, alias, name, parent, initializer, prerequisites, project_local, node_local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details, finisher) =>
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

        finisher() if typeof finisher == 'function'

      runtime_exception: (exit = false) =>
        (err) =>
          Madul.FIRE "!.#{@constructor.name}.runtime-exception",
            stack:     err.stack
            message:   err.message
            timestamp: microtime.now()

          process.exit(1) if exit == 'DIE_ON_EXCEPTION'

      set: (prop, val) =>
        proto = @.__proto__
        mod   = available[strip proto.constructor.name.toLowerCase()]

        if mod?
          mod.__proto__[prop] = val

      _report: (method, state, id, args, breaker) =>
        invoke = undefined
        params =
          uuid:      id
          args:      args
          timestamp: microtime.now()

        if state == 'reject'
          if typeof breaker == 'function'
            stop = new Error()
            stop.break = true

            breaker stop

          @warn "#{method}.#{state}", params
        else
          @fire "#{method}.#{state}", params

      _respond: (proto, method, id, deferred) =>
        (state, data, breaker) =>
          process.nextTick =>
            deferred[state] data

            proto._report method, state, id, data, breaker

      _prep_invocation: (proto, method, input, def) =>
        out = [ ]
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def
        e   = (brk) =>
          error = (err) => res 'reject', err, brk

          if typeof brk == 'function'
            error
          else
            error brk

        if Array.isArray input
          out = out.concat input
        else if typeof input == 'object'
          out.push input
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"

          proto.warn.call proto, 'input.invalid', msg

          throw new Error msg

        out.push (out) => res 'resolve', out
        out.push e
        out.push (out) => res 'notify',  out

        proto._report method, 'invoke', id, out

        out

      _process_decorators: (proto, type) =>
        if Array.isArray proto[type]
          proto[type].map (b) => Madul.PARSE_SPEC(b).ref
        else if typeof proto[type] == 'string'
          [ Madul.PARSE_SPEC(proto[type]).ref ]
        else
          [ ]

      _do_wrap: (proto, method, wrapped) =>
        if SKIP_WRAP.includes method
          wrapped()
        else
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def   = q.defer()
              args  = Array.prototype.slice.call arguments
              input = proto._prep_invocation proto, method, args, def

              try
                proto["_#{method}"].apply proto, input
              catch e
                failed = if input[0].fail? then input[0].fail else input[input.length - 2]

                proto.warn.call proto, 'runtime-exception', stack: e.stack, message: e.message

                failed e.message

              def.promise

            INITIALIZERS proto.constructor.name, method if method[0] == '$'

            WRAPPED[proto.constructor.name].push method

            wrapped()
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = proto[method].validate

              proto[method].validators = for val, i in decs
                "#{i}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  for v in val
                    decs.push v
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      for V in v
                        decs.push V
                    else
                      decs.push v
                else
                  decs.push val

              proto[method].validators = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  proto[method].validators.push "#{key}": for v in val
                    Madul.PARSE_SPEC(v).ref
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      proto[method].validators.push "#{key}.#{k}": for V in v
                        Madul.PARSE_SPEC(V).ref
                    else
                      proto[method].validators.push "#{key}.#{k}": Madul.PARSE_SPEC(v).ref
                else
                  proto[method].validators.push "#{key}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]

              proto[method].validators = [ { 0: Madul.PARSE_SPEC(proto[method].validate).ref }]
            else if typeof proto[method].validate != 'undefined'
              proto.warn.call proto, 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            if Array.isArray proto[method].before
              decs = decs.concat proto[method].before
            else if typeof proto[method].before == 'string'
              decs = decs.concat [ proto[method].before ]

            if Array.isArray proto[method].after
              decs = decs.concat proto[method].after
            else if typeof proto[method].after == 'string'
              decs = decs.concat [ Madul.PARSE_SPEC proto[method].after ]

            deduped = decs.filter (e, i, a) => a.indexOf(e) == i

            proto.fire.call proto, 'decorators.hydrate', deduped

            handle_err = (fn, args, next, reject) =>
              (err) =>
                proto.warn.call proto, "#{fn}.validator.failed", args
                reject err

                stop = new Error()
                stop.break = true

                next stop

            @_do_hydrate proto, deduped, (errors) =>
              if errors?
                wrapped errors
              else
                proto["_#{method}"] = proto[method]

                proto[method] = =>
                  def = q.defer()
                  me  = proto["_#{method}"]

                  if args_format == 'ARRAY'
                    args = Array.prototype.slice.call arguments
                  else if args_format == 'OBJECT'
                    args = arguments[0]
                  else
                    proto.warn.call proto, 'cannot-continue', 'No arg format specified'

                    return def.reject 'No arg format specified'

                  before = @_process_decorators me, 'before'
                  after  = @_process_decorators me, 'after'

                  q.Promise (resolve, reject) =>
                    async.eachSeries me.validators, (v, next) =>
                      arg       = Object.keys(v)[0]
                      validator = v[arg]
                      input     = arg
                      prop      = args

                      for a in arg.split '.'
                        prop  = prop[a]
                        input = a

                      if Array.isArray validator
                        async.eachSeries validator, (v, nxt) =>
                          proto.fire.call proto, 'validator.execute', "#{v}": prop

                          proto[v].EXECUTE.call proto[v], input, prop
                            .then nxt
                            .catch handle_err v, { "#{input}": prop }, nxt, (err) =>
                              reject err
                              def.reject err
                        , next
                      else
                        proto.fire.call proto, 'validator.execute', "#{validator}": prop

                        proto[validator].EXECUTE.call proto[validator], input, prop
                          .then next
                          .catch handle_err v, { "#{input}": prop }, next, (err) =>
                            reject err
                            def.reject err
                    , resolve
                  .then =>
                    q.Promise (resolve, reject) =>
                      async.eachSeries before, (b, next) =>
                        proto.fire.call proto, 'before_filter.execute', "#{b}": args

                        proto[b].before.call proto[b], args
                          .then next
                          .catch handle_err b, args, next, (err) =>
                            reject err
                            def.reject err
                      , resolve
                  .then =>
                    input = proto._prep_invocation proto, method, args, def

                    try
                      me.behavior.apply me, input
                    catch e
                      failed = if input[0].fail? then input[0].fail else input[input.length - 2]

                      me.warn.call me, 'runtime-exception', stack: e.stack, message: e.message

                      failed e.message
                  .then (result) =>
                    q.Promise (resolve, reject) =>
                      if after.length > 0
                        async.eachSeries after, (a, next) =>
                          proto.fire.call proto, 'after_filter.execute', "#{a}": args

                          proto[a].after.call proto[a], result
                            .then next
                            .catch handle_err b, args, next, (err) =>
                              reject err
                              def.reject err
                        , => resolve result
                      else
                        process.nextTick => resolve result
                  .then  (out) => def.resolve out
                  .catch (err) => def.reject  err

                  def.promise

                INITIALIZERS proto.constructor.name, method if method[0] == '$'

                WRAPPED[proto.constructor.name].push method

                wrapped()
          else
            proto.warn.call proto, 'cannot-wrap', method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method, (errors) =>
              if errors?
                stop = new Error()
                stop.break = true

                next stop
              else
                next()
          , (errors) =>
            if errors?
              stop = new Error()
              stop.break = true

              completed stop
            else
              @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, (errors) =>
                if errors?
                  stop = new Error()
                  stop.break = true

                  next stop
                else
                  HYDRATED[name] = true

                  for listener in HYRDATION_LISTENERS[name]
                    listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, done, fail) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then  done
            .catch fail
        else
          done mod

      _load: (me, name, path, loaded, fail) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded mod
        , fail

      _check: (me, path, dep, ref, finished) =>
        error = true

        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            finished 'NOT_FOUND'
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) =>
                    error = undefined
                    me._do_add me, ref, next
                  , (err) =>
                    stop = new Error()
                    stop.break = true

                    next stop
                else
                  next()
            , => finished error

      _do_add: (me, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = available[strip ref]

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, ref, next
        , (err) =>
          stop = new Error()
          stop.break = true

          next stop

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]
        errors  = [ ]

        async.each deps, (d, next) =>
          spec = Madul.PARSE_SPEC d

          if spec.prerequisites?
            insert_at = for p in spec.prerequisites
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: spec.alias, execute: spec.initializer
          else if spec.initializer?
            initers.push alias: spec.alias, execute: spec.initializer

          if typeof proto[underscore spec.ref] == 'undefined'
            if available[strip spec.ref]? == true
              proto._do_add proto, spec.ref, next
            else
              if spec.parent?
                proto.fire.call proto, 'search_root.load', { name: spec.name, alias: spec.alias, parent: spec.parent }

                @_do_hydrate proto, [ spec.parent ], (errors) =>
                  if errors?
                    stop = new Error()
                    stop.break = true

                    next stop
                  else
                    if SEARCH_ROOTS[spec.parent] == undefined
                      SEARCH_ROOTS[spec.parent] = @_find_code_root spec.parent

                    proto._check proto, SEARCH_ROOTS[spec.parent], spec.name, spec.ref, next
              else if spec.node_local
                key = @_find_require_key proto.constructor.name

                async.eachSeries require.cache[key].paths, (path, nxt) =>
                  @_load_from_package_json proto, path, spec.name, spec.ref, nxt, =>
                    details = not_found: spec.name
                    stop    = new Error()

                    stop.break = true

                    proto.warn.call proto, 'hydrating', details

                    errors.push(details)

                    next()
                    nxt stop
              else if spec.project_local
                proto._check proto, LOCALS[proto.constructor.name], spec.name, spec.ref, (err) =>
                  if err?
                    details = not_found: spec.name
                    stop    = new Error()

                    stop.break = true

                    proto.warn.call proto, 'hydrating', details

                    errors.push(details)

                    next stop
                  else
                    next()
              else
                try
                  proto._add proto, spec.ref, spec.name, next
                catch e
                  path = "#{process.cwd()}/node_modules"

                  @_load_from_package_json proto, path, spec.name, spec.ref, next, =>
                    pth = LOCALS[proto.constructor.name]

                    try
                      proto._check proto, pth, spec.name, spec.ref, (err) =>
                        if err?
                          proto._check proto, "#{process.cwd()}/dist", spec.name, spec.ref, next
                        else
                          next()

          else
            next()
        , (err) =>
          if err?
            proto.warn.call proto, 'hydration.halt', errors

            hydration_complete errors
          else
            async.eachSeries initers, (initer, next) =>
              proto[initer.execute].apply(@).then next
            , hydration_complete

      _load_from_package_json: (proto, path, name, ref, success, fail) =>
        pkg = "#{path}/#{name}/package.json"

        fs.stat pkg, (err, stat) =>
          if stat?.isFile()
            fs.readFile pkg, 'utf8', (err, data) =>
              json = JSON.parse data
              main = json.main || json._main || 'index.js'
              path = "#{path}/#{name}/#{main}"

              proto._add proto, ref, path, success
          else
            fail()

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply proto
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _do_find: (thing, cb) =>
        file  = thing.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            cb key

        found
          .filter (f) => f?
          .sort((a, b) => a.length - b.length)[0]

      _find_require_key: (resource) =>
        @_do_find resource, (key) => key

      _find_code_root: (resource) =>
        @_do_find resource, (key) => key.substring(0, key.lastIndexOf '/').split '/'
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, (errors) =>
            if errors?
              deferred.reject errors
            else
              @_wrap_methods proto, (err) =>
                if err?
                  deferred.reject err
                else
                  @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    SKIP_WRAP = [
      'constructor'
      'initialize'
      'details'
      'fire'
      'warn'
      'listen'
      'set'
      'runtime_exception'
    ]

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      WRAPPED[cls] = [ ] unless WRAPPED[cls]?

      WRAPPED[cls].indexOf(method) < 0

    determine_local = (token) ->
      project_local = false
      node_local    = false
      name          = token.substring 1, token.length

      if token[0] == '.'
        project_local = true
      else if token[0] == '~'
        node_local = true
      else
        name = token

      [project_local, node_local, name]

    parse_name_and_local = (tokens) ->
      [project_local, node_local, name] = determine_local tokens[0].trim()

      if tokens.length == 2
        alias = tokens[1].trim()
      else if tokens.length == 1
        alias = name
      else
        return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

      [project_local, node_local, name, alias]

    parse_alias_and_parent = (token) ->
      t = token.split '->'

      if t[0].indexOf('#') > -1
        r      = t[0].split '#'
        parent = r[0].trim()
        t[0]   = r[1]

      [parent, t]

    extract_properties = (token) ->
      [parent, t] = parse_alias_and_parent token
      [project_local, node_local, name, alias] = parse_name_and_local t

      [project_local, node_local, name, alias, parent]

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        [project_local, node_local, name, alias, parent] = extract_properties tokens[0]

        if tokens.length == 2
          initializer = tokens[1].trim()
          toks        = initializer.split ':'
          initializer = toks[0].trim()

          if toks.length == 2
            prerequisites = toks[1].split(',').map (p) => p.trim()
          else if toks.length > 2
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length > 2
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || name, alias, name, parent, initializer, prerequisites, project_local, node_local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details, finisher) =>
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

        finisher() if typeof finisher == 'function'

      runtime_exception: (exit = false) =>
        (err) =>
          Madul.FIRE "!.#{@constructor.name}.runtime-exception",
            stack:     err.stack
            message:   err.message
            timestamp: microtime.now()

          process.exit(1) if exit == 'DIE_ON_EXCEPTION'

      set: (prop, val) =>
        proto = @.__proto__
        mod   = available[strip proto.constructor.name.toLowerCase()]

        if mod?
          mod.__proto__[prop] = val

      _report: (method, state, id, args, breaker) =>
        invoke = undefined
        params =
          uuid:      id
          args:      args
          timestamp: microtime.now()

        if state == 'reject'
          if typeof breaker == 'function'
            stop = new Error()
            stop.break = true

            breaker stop

          @warn "#{method}.#{state}", params
        else
          @fire "#{method}.#{state}", params

      _respond: (proto, method, id, deferred) =>
        (state, data, breaker) =>
          process.nextTick =>
            deferred[state] data

            proto._report method, state, id, data, breaker

      _prep_invocation: (proto, method, input, def) =>
        out = [ ]
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def
        e   = (brk) =>
          error = (err) => res 'reject', err, brk

          if typeof brk == 'function'
            error
          else
            error brk

        if Array.isArray input
          out = out.concat input
        else if typeof input == 'object'
          out.push input
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"

          proto.warn.call proto, 'input.invalid', msg

          throw new Error msg

        out.push (out) => res 'resolve', out
        out.push e
        out.push (out) => res 'notify',  out

        proto._report method, 'invoke', id, out

        out

      _process_decorators: (proto, type) =>
        if Array.isArray proto[type]
          proto[type].map (b) => Madul.PARSE_SPEC(b).ref
        else if typeof proto[type] == 'string'
          [ Madul.PARSE_SPEC(proto[type]).ref ]
        else
          [ ]

      _do_wrap: (proto, method, wrapped) =>
        if SKIP_WRAP.includes method
          wrapped()
        else
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def   = q.defer()
              args  = Array.prototype.slice.call arguments
              input = proto._prep_invocation proto, method, args, def

              try
                proto["_#{method}"].apply proto, input
              catch e
                failed = if input[0].fail? then input[0].fail else input[input.length - 2]

                proto.warn.call proto, 'runtime-exception', stack: e.stack, message: e.message

                failed e.message

              def.promise

            INITIALIZERS proto.constructor.name, method if method[0] == '$'

            wrapped()
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = proto[method].validate

              proto[method].validators = for val, i in decs
                "#{i}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  for v in val
                    decs.push v
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      for V in v
                        decs.push V
                    else
                      decs.push v
                else
                  decs.push val

              proto[method].validators = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  proto[method].validators.push "#{key}": for v in val
                    Madul.PARSE_SPEC(v).ref
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      proto[method].validators.push "#{key}.#{k}": for V in v
                        Madul.PARSE_SPEC(V).ref
                    else
                      proto[method].validators.push "#{key}.#{k}": Madul.PARSE_SPEC(v).ref
                else
                  proto[method].validators.push "#{key}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]

              proto[method].validators = [ { 0: Madul.PARSE_SPEC(proto[method].validate).ref }]
            else if typeof proto[method].validate != 'undefined'
              proto.warn.call proto, 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            if Array.isArray proto[method].before
              decs = decs.concat proto[method].before
            else if typeof proto[method].before == 'string'
              decs = decs.concat [ proto[method].before ]

            if Array.isArray proto[method].after
              decs = decs.concat proto[method].after
            else if typeof proto[method].after == 'string'
              decs = decs.concat [ Madul.PARSE_SPEC proto[method].after ]

            deduped = decs.filter (e, i, a) => a.indexOf(e) == i

            proto.fire.call proto, 'decorators.hydrate', deduped

            handle_err = (fn, args, next, reject) =>
              (err) =>
                proto.warn.call proto, "#{fn}.validator.failed", args
                reject err.message

                stop = new Error()
                stop.break = true

                next stop

            @_do_hydrate proto, deduped, =>
              proto["_#{method}"] = proto[method]

              proto[method] = =>
                def = q.defer()
                me  = proto["_#{method}"]

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments
                else if args_format == 'OBJECT'
                  args = arguments[0]
                else
                  proto.warn.call proto, 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                before = @_process_decorators me, 'before'
                after  = @_process_decorators me, 'after'

                q.Promise (resolve, reject) =>
                  async.eachSeries me.validators, (v, next) =>
                    arg       = Object.keys(v)[0]
                    validator = v[arg]
                    input     = arg
                    prop      = args

                    for a in arg.split '.'
                      prop  = prop[a]
                      input = a

                    if Array.isArray validator
                      async.eachSeries validator, (v, nxt) =>
                        proto.fire.call proto, 'validator.execute', "#{v}": prop

                        proto[v].EXECUTE.call proto[v], input, prop
                          .then nxt
                          .catch handle_err v, { "#{input}": prop }, nxt, reject
                      , next
                    else
                      proto.fire.call proto, 'validator.execute', "#{validator}": prop

                      proto[validator].EXECUTE.call proto[validator], input, prop
                        .then next
                        .catch handle_err v, { "#{input}": prop }, next, reject
                  , resolve
                .then =>
                  q.Promise (resolve, reject) =>
                    async.eachSeries before, (b, next) =>
                      proto.fire.call proto, 'before_filter.execute', "#{b}": args

                      proto[b].before.call proto[b], args
                        .then next
                        .catch handle_err b, args, next, reject
                    , resolve
                .then =>
                  input = proto._prep_invocation proto, method, args, def

                  try
                    me.behavior.apply me, input
                  catch e
                    failed = if input[0].fail? then input[0].fail else input[input.length - 2]

                    me.warn.call me, 'runtime-exception', stack: e.stack, message: e.message

                    failed e.message
                .then (result) =>
                  q.Promise (resolve, reject) =>
                    if after.length > 0
                      async.eachSeries after, (a, next) =>
                        proto.fire.call proto, 'after_filter.execute', "#{a}": args

                        proto[a].after.call proto[a], result
                          .then next
                          .catch handle_err b, args, next, reject
                      , => resolve result
                    else
                      process.nextTick => resolve result
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise

              INITIALIZERS proto.constructor.name, method if method[0] == '$'

              wrapped()
          else
            proto.warn.call proto, 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method, next
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, =>
                HYDRATED[name] = true

                for listener in HYRDATION_LISTENERS[name]
                  listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, callback) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then callback
        else
          callback mod

      _load: (me, name, path, loaded) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded mod

      _check: (me, path, dep, ref, finished) =>
        error = true

        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            finished 'NOT_FOUND'
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) =>
                    error = undefined
                    me._do_add me, ref, next
                else
                  next()
            , => finished error

      _do_add: (me, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = available[strip ref]

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, ref, next

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]

        async.each deps, (d, next) =>
          spec = Madul.PARSE_SPEC d

          if spec.prerequisites?
            insert_at = for p in spec.prerequisites
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: spec.alias, execute: spec.initializer
          else if spec.initializer?
            initers.push alias: spec.alias, execute: spec.initializer

          if typeof proto[underscore spec.ref] == 'undefined'
            if available[strip spec.ref]? == true
              proto._do_add proto, spec.ref, next
            else
              if spec.parent?
                proto.fire.call proto, 'search_root.load', { name: spec.name, alias: spec.alias, parent: spec.parent }

                @_do_hydrate proto, [ spec.parent ], =>
                  if SEARCH_ROOTS[spec.parent] == undefined
                    SEARCH_ROOTS[spec.parent] = @_find_code_root spec.parent

                  proto._check proto, SEARCH_ROOTS[spec.parent], spec.name, spec.ref, next
              else if spec.node_local
                key = @_find_require_key proto.constructor.name

                async.eachSeries require.cache[key].paths, (path, nxt) =>
                  @_load_from_package_json proto, path, spec.name, spec.ref, nxt, =>
                    stop = new Error()
                    stop.break = true

                    next()
                    nxt stop
              else if spec.project_local
                proto._check proto, LOCALS[proto.constructor.name], spec.name, spec.ref, next
              else
                try
                  proto._add proto, spec.ref, spec.name, next
                catch e
                  path = "#{process.cwd()}/node_modules"

                  @_load_from_package_json proto, path, spec.name, spec.ref, next, =>
                    pth = LOCALS[proto.constructor.name]

                    try
                      proto._check proto, pth, spec.name, spec.ref, (err) =>
                        if err?
                          proto._check proto, "#{process.cwd()}/dist", spec.name, spec.ref, next
                        else
                          next()

          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            proto[initer.execute].apply(@).then next
          , hydration_complete

      _load_from_package_json: (proto, path, name, ref, success, fail) =>
        pkg = "#{path}/#{name}/package.json"

        fs.stat pkg, (err, stat) =>
          if stat?.isFile()
            fs.readFile pkg, 'utf8', (err, data) =>
              json = JSON.parse data
              main = json.main || json._main || 'index.js'
              path = "#{path}/#{name}/#{main}"

              proto._add proto, ref, path, success
          else
            fail()

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply proto
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _do_find: (thing, cb) =>
        file  = thing.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            cb key

        found
          .filter (f) => f?
          .sort((a, b) => a.length - b.length)[0]

      _find_require_key: (resource) =>
        @_do_find resource, (key) => key

      _find_code_root: (resource) =>
        @_do_find resource, (key) => key.substring(0, key.lastIndexOf '/').split '/'
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, => @_wrap_methods proto, => @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul