 'use strict';
-{defineModule, log, min, max} = require 'art-standard-lib'
+{clone, defineModule, log, min, max} = require 'art-standard-lib'
 {BaseClass} = require 'art-class-system'
-{rect} = require 'art-atomic'
+{rect, Rectangle} = require 'art-atomic'
+{compositeModeMap} = require 'art-canvas'
 
 defineModule module, ->
 

      @reset()

    reset: ->
      @totalDrawArea = null
      @clippingArea = null

    @getter
      drawArea: -> @totalDrawArea || rect()

    addDrawArea: (drawArea) ->
      if @clippingArea
        drawAreaBefore = drawArea
        drawAreaBeforeString = drawArea.toString()
        drawArea = drawArea.intersection @clippingArea
      @totalDrawArea = drawArea.unionInto @totalDrawArea
      # log drawAreaCollector: addDrawArea: {@clippingArea, drawArea, @totalDrawArea, drawAreaBefore, drawAreaBeforeString}

    fillShape: (drawMatrix, options, pathFunction, pathSize, pathOptions) ->
      # log drawAreaCollector: fillShape: {pathSize, expanded: expandDrawAreaByShadow pathSize, options}
      @addDrawArea drawMatrix.transformBoundingRect expandDrawAreaByShadow pathSize, options

    strokeShape: (drawMatrix, options, pathFunction, pathSize, pathOptions) ->
      @addDrawArea drawMatrix.transformBoundingRect expandDrawAreaByOutline(
        expandDrawAreaByShadow pathSize, options
        options
        pathFunction
      )

    # returns an existing-value
    openClipping: (area, drawMatrix, pathSize, areaArg2) ->

    closeClipping: (oldClipArea) ->
      @clippingArea = oldClipArea

    fillShape: (drawMatrix, options, pathFunction, pathSize, pathOptions) ->
      # log drawAreaCollector: fillShape: {pathSize, expanded: expandDrawAreaByShadow pathSize, options}
      @compositeDrawAreas options.compositeMode,
        drawMatrix.transformBoundingRect expandDrawAreaByShadow pathSize, options

    strokeShape: (drawMatrix, options, pathFunction, pathSize, pathOptions) ->
      @compositeDrawAreas options.compositeMode,
        drawMatrix.transformBoundingRect expandDrawAreaByOutline(
          expandDrawAreaByShadow pathSize, options
          options
          pathFunction
        )

    drawDrawable: (child, elementToTargetMatrix) ->
      @compositeDrawAreas child.compositeMode,
        elementToTargetMatrix.transformBoundingRect child.elementSpaceDrawArea

    compositeDrawAreas: (compositeMode, sourceDrawArea) ->

      if @targetDrawArea && @clippingArea && !@clippingArea.contains @targetDrawArea
        clippingDoesNotCoverTargetDrawArea = true

      sourceDrawArea = @clipDrawArea sourceDrawArea

      out = switch compositeModeMap[compositeMode]
        # new drawArea is the intersection (alphaMask)
        when "destination-in", "source-in"    then reducesDrawArea = true; sourceDrawArea.intersectInto @targetDrawArea

        # new drawArea is only sourceDrawArea (inverseAlphaMask)
        when "destination-atop", "source-out" then reducesDrawArea = true; sourceDrawArea

        # new drawArea is only targetDrawAaea
        when "destination-out", "source-atop" then @targetDrawArea

        # new drawArea is the union
        else sourceDrawArea.unionInto @targetDrawArea

      @targetDrawArea = if reducesDrawArea && clippingDoesNotCoverTargetDrawArea
        out.unionInto @targetDrawArea
      else out
