# -*- coding: utf-8 -*-

import math


class Command:
    inicoms = ("IN", "SP", "LT")  # nicht benutzt
    scalecoms = ("PA", "PD", "PR", "PU", "CI")  # Liste skalierbarer HPGL-Befehle
    movecoms = ("PA", "PD", "PU")  # Liste verschiebbarer HPGL-Befehle
    abscoms = ("PA", "PD", "PU")
    relcoms = ("PR")
    arccoms = ("CI", "AA")

    def __init__(self, name, *args):
        self.name = name
        self.args = args

    @property
    def scalable(self):
        return self.name in Command.scalecoms and self.args

    @property
    def movable(self):
        return self.name in Command.movecoms and self.args

    @property
    def x(self):
        return self.args[0] if self.args else None

    @property
    def y(self):
        return self.args[-1] if self.args else None

    def __trunc__(self):
        return Command(self.name, *[int(arg) for arg in self.args])

    def __len__(self):
        return len(str(self))

    def __str__(self):
        return self.name + ",".join(str(int(arg)) for arg in self.args) + ";"

    def __mul__(self, factor):
        if not self.scalable:
            return self
        if type(factor) == type(0) or type(factor) == type(0.0):
            factor = (factor, factor)
        return Command(self.name, (self.args[0] * factor[0]), (self.args[1] * factor[1])) \
            if len(self.args) > 1 else \
            Command(self.name, (self.args[0] * factor[0]))

    def __add__(self, addend):
        if not self.movable:
            return self
        if type(addend) == type(0) or type(addend) == type(0.0):
            addend = (addend, addend)
        return Command(self.name, (self.x + addend[0]), (self.y + addend[1]))

    def __sub__(self, addend):
        if type(addend) == type(0) or type(addend) == type(0.0):
            addend = (addend, addend)
        return self + (-addend[0], -addend[1])

    def rotate(self, angl):
        if not self.movable:
            return self
        cosa = math.cos(angl * math.pi / 180)
        sina = math.sin(angl * math.pi / 180)
        return Command(self.name, (self.x * cosa - self.y * sina), (self.y * cosa + self.x * sina))

    def flip(self):
        if not self.movable:
            return self
        return Command(self.name, self.x, -self.y)
