from chiplotle.geometry.core.coordinate import Coordinate
from chiplotle.hpgl import commands as hpgl
import numpy

## TODO: this works, but is quite ugly. Refactor!
def relativize(data):
   '''Converts all absolute coordinate commands (PA, RA, EA, AA)
   into relative commands (PR, RR, ER, AR), so that everything
   has in realtive coordinate values.'''
   ## main body...
   last_position = None
   delta = None
   result = [ ]
   for e in data:
      ## absolute...
      if isinstance(e, (hpgl.PA, hpgl.RA, hpgl.EA, hpgl.AA)):
         if isinstance(e, hpgl.PA):
            ## handle delta...
            if not last_position is None:
               delta = e.xy[0] - last_position
            last_position = e.xy[-1]
         else:
            ## handle delta...
            if not last_position is None:
               delta = e.xy - last_position
            last_position = e.xy
         result += _return_relative_from_absolute(e, delta)

      ## relative...
      elif isinstance(e, (hpgl.PR, hpgl.RR, hpgl.ER, hpgl.AR)):
         if isinstance(e, hpgl.PR):
            coords = [list(c) for c in e.xy]
            if not last_position is None:
               last_position += Coordinate(*numpy.sum(coords, axis = 0))
            else:
               last_position = Coordinate(*numpy.sum(coords, axis = 0))
            result.append(e)
         else:
            last_position = (last_position or 0) + e.xy

      else:
         result.append(e)
   return result


def _return_relative_from_absolute(command, delta):
   result = [ ]
   if isinstance(command, hpgl.PA):
      if delta is not None:
         result.append(hpgl.PR([delta]))
      coords = [list(c) for c in command.xy]
      diff = numpy.diff(coords, axis=0).tolist( )
      if len(diff) > 0:
         result.append(hpgl.PR(diff))
   elif isinstance(command, hpgl.RA) and delta is not None:
      result.append(hpgl.RR(delta))
   elif isinstance(command, hpgl.EA) and delta is not None:
      result.append(hpgl.ER(delta))
   elif isinstance(command, hpgl.AA) and delta is not None:
      result.append(hpgl.AR(delta))
   return result


## Trash...
#def relativize(data):
#   '''Converts all absolute coordinate commands (PA, RA, EA, AA)
#   into relative commands (PR, RR, ER, AR), so that everything
#   has in realtive coordinate values.'''
#   def _return_relative_from_absolute(command, delta):
#      result = [ ]
#      if isinstance(command, hpgl.PA):
#         if delta is not None:
#            result.append(hpgl.PR(delta))
#         diff = numpy.diff(command.xy, axis=0)
#         if len(diff) > 0:
#            result.append(hpgl.PR(diff))
#      elif isinstance(command, hpgl.RA) and delta is not None:
#         result.append(hpgl.RR(delta))
#      elif isinstance(command, hpgl.EA) and delta is not None:
#         result.append(hpgl.ER(delta))
#      elif isinstance(command, hpgl.AA) and delta is not None:
#         result.append(hpgl.AR(delta))
#      return result
#
#   ## main body...
#   last_position = None
#   delta = None
#   result = [ ]
#   for e in data:
#      ## absolute...
#      if isinstance(e, (hpgl.PA, hpgl.RA, hpgl.EA, hpgl.AA)):
#         ## handle delta...
#         if not last_position is None:
#            delta = e.xy[0] - last_position
#         last_position = e.xy[-1]
#         result += _return_relative_from_absolute(e, delta)
#      ## relative...
#      elif isinstance(e, (hpgl.PR, hpgl.RR, hpgl.ER, hpgl.AR)):
#         if not last_position is None:
#            last_position += numpy.sum(e.xy, axis = 0)
#         else:
#            last_position = numpy.sum(e.xy, axis = 0)
#         result.append(e)
#      else:
#         result.append(e)
#   return result
#
