#!/usr/bin/env ruby

# Add de extension directory for the path:
$: << $0.gsub( /[^\/]*$/, '' )

# Start the Magick Machine:
require 'RubyInk'

pump = $ink.args['pump'].to_f

$ink.eachSelectedElement {
  |el|

  if el.class != SVG::PathElement
    # Only Paths are suported by now.
    fail TypeError.new("The <#{el.name} id=\"#{el.id}\"> is not a <path> element.")
  end

  transform = el.transform

  biggerX, biggerY, lowerX, lowerY = nil
  el.nodes.each { |n|
    if n.x
      biggerX = n.x  if !biggerX
      biggerY = n.y  if !biggerY
      lowerX  = n.x  if !lowerX
      lowerY  = n.y  if !lowerY
      biggerX = n.x  if biggerX < n.x
      biggerY = n.y  if biggerY < n.y
      lowerX  = n.x  if lowerX  > n.x
      lowerY  = n.y  if lowerY  > n.y
      n.controls.each { |c|
        biggerX = c[:x]  if biggerX < c[:x]  if c[:x]
        biggerY = c[:y]  if biggerY < c[:y]  if c[:y]
        lowerX  = c[:x]  if lowerX  > c[:x]  if c[:x]
        lowerY  = c[:y]  if lowerY  > c[:y]  if c[:y]
        biggerX = n.x + c[:rx]  if biggerX < ( n.x + c[:rx] )  if c[:rx]
        biggerY = n.y + c[:ry]  if biggerY < ( n.y + c[:ry] )  if c[:ry]
        lowerX  = n.x - c[:rx]  if lowerX  > ( n.x - c[:rx] )  if c[:rx]
        lowerY  = n.y - c[:ry]  if lowerY  > ( n.y - c[:ry] )  if c[:ry]
      }
    end
  }

  defs = $ink.svgDoc.getElementsByTagName( 'defs' )[0]

  maskLigthId = $ink.svgDoc.generateId 'mask'
  mask = defs.add_element( 'mask', { 'id' => maskLigthId, 'maskUnits' => 'userSpaceOnUse' } )
  maskLigthG = mask.add_element SVG::GroupElement.new

  filterLigthId = $ink.svgDoc.generateId 'filter'
  filter = defs.add_element( 'filter', { 'id' => filterLigthId } )
  filter.add_element( 'feGaussianBlur', { 'stdDeviation' => pump/2 } )

  maskShadowId = $ink.svgDoc.generateId 'mask'
  mask = defs.add_element( 'mask', { 'id' => maskShadowId, 'maskUnits' => 'userSpaceOnUse' } )
  maskShadowG = mask.add_element SVG::GroupElement.new

  filterShadowId = $ink.svgDoc.generateId 'filter'
  filter = defs.add_element( 'filter', { 'id' => filterShadowId } )
  filter.add_element( 'feGaussianBlur', { 'stdDeviation' => pump } )

  clipId = $ink.svgDoc.generateId 'clip'
  clip = defs.add_element( 'clipPath', { 'id'=>clipId, 'clipPathUnits'=>'userSpaceOnUse' } )
  #clip.name = 'clip-path'

  # Create a group for the effect:
  base = el.parent.add_element SVG::GroupElement.new
  # Put the element in a group:
  base.add_element el
  # Create a group for the Light and Shadow:
  base = base.add_element SVG::GroupElement.new
  base.attributes['clip-path'] = "url(##{clipId})"

  clone = clip.add_element el.clone
  #clone.transform = nil

  # Create Ligth:
  gLigth = base.add_element SVG::GroupElement.new(
                  { 'transform' => "translate(#{pump/2},#{pump/2})" } )
  gLigth.style[:filter] = "url(##{filterLigthId})"
  clone1 = gLigth.add_element el.clone
  clone1.attributes['mask'] = "url(##{maskLigthId})"
  clone1.style[:opacity] = 0.7
  clone1.style[:fill] = '#FFF'
  clone1.style['fill-opacity'] = 1
  clone1.style[:stroke] = 'none'
  rect = maskLigthG.add_element SVG::RectElement.new
  rect.x = lowerX
  rect.y = lowerY
  rect.width = biggerX - lowerX
  rect.height = biggerY - lowerY
  rect.style[:fill] = '#FFF'
  clone2 = maskLigthG.add_element el.clone
  clone2.style[:opacity] = 1
  clone2.style[:fill] = '#000'
  clone2.style['fill-opacity'] = 1
  clone2.style[:stroke] = '#000'
  clone2.style['stroke-opacity'] = 1
  clone2.transform = "translate(#{pump},#{pump})"

  # Create Shadow:
  gShadow = base.add_element SVG::GroupElement.new
  gShadow.style[:filter] = "url(##{filterShadowId})"
  rectS = gShadow.add_element SVG::RectElement.new
  rectS.x = lowerX - (pump*3)
  rectS.y = lowerY - (pump*3)
  rectS.width = biggerX - lowerX + (pump*3)
  rectS.height = biggerY - lowerY + (pump*3)
  rectS.attributes['mask'] = "url(##{maskShadowId})"
  rectS.style[:fill] = '#000'
  rectS.style[:opacity] = 0.7
  rectS.transform = transform
  rect = maskShadowG.add_element SVG::RectElement.new
  rect.x = lowerX - (pump*3)
  rect.y = lowerY - (pump*3)
  rect.width = biggerX - lowerX + (pump*3)
  rect.height = biggerY - lowerY + (pump*3)
  rect.style[:fill] = '#FFF'
  clone2 = maskShadowG.add_element el.clone
  clone2.style[:opacity] = 1
  clone2.style[:fill] = '#000'
  clone2.style['fill-opacity'] = 1
  clone2.style[:stroke] = '#000'
  clone2.style['stroke-opacity'] = 1
  clone2.transform = "translate(#{-pump},#{-pump})"
}

$ink.dumpSvgDoc

