

class Point:
    def __init__(self, _x, _y, _r=0, _h=None):
        self.x = _x
        self.y = _y
        self.r = _r
        self.h = _h


class MachineConfig:
    def __init__(self):
        self.head_num = 6
        self.slot_num = 120
        self.slot_intv = 15
        self.head_intv = 30
        self.slotf1_pos = Point(-31.327, 44.)
        self.slotr1_pos = Point(807., 810.545)
        self.stopper_pos = Point(665.150, 124.738)
        self.anc_pos = Point(336.457, 626.230)

        self.pick_time = .078   # 拾取用时
        self.place_time = .051  # 贴装用时
        self.nozzle_install_time = 0.9       # 装吸嘴用时
        self.nozzle_uninstall_time = 0.75    # 卸吸嘴用时


class OptResult:
    def __init__(self):
        self.part = []
        self.layer = []
        self.cycle = []
        self.slot = []
        self.point = []
        self.sequence = []

    def __add__(self, other):
        self.part.extend(other.part)
        self.layer.extend(other.layer)
        self.cycle.extend(other.cycle)
        self.slot.extend(other.slot)
        self.point.extend(other.point)
        self.sequence.extend(other.sequence)

        return self


class OptInfo:
    def __init__(self):
        self.total_time = .0        # 总组装时间
        self.total_points = 0       # 总贴装点数
        self.total_components = 0   # 总元件数

        self.pickup_time = .0       # 拾取过程运动时间
        self.round_time = .0        # 往返基座/基板运动时间
        self.place_time = .0        # 贴装过程运动时间
        self.operation_time = .0    # 拾取/贴装/换吸嘴等机械动作用时

        self.cycle_counter = 0           # 周期数
        self.nozzle_change_counter = 0   # 吸嘴更换次数
        self.anc_round_counter = 0       # 前往ANC次数
        self.pickup_counter = 0          # 拾取次数

        self.total_distance = .0         # 总移动路径
        self.place_distance = .0         # 贴装移动路径
        self.pickup_distance = .0        # 拾取移动路径

    def print(self):
        print('-Cycle counter: {}'.format(self.cycle_counter))

        print(f'-Nozzle change counter: {self.nozzle_change_counter: d}')
        print(f'-ANC round: {self.anc_round_counter: d}')
        print(f'-Pick operation counter: {self.pickup_counter: d}')
        print(f'-Pick time: {self.pickup_time: .3f}, Pick distance: {self.pickup_distance: .3f}')
        print(f'-Place time: {self.place_time: .3f}, Place distance: {self.place_distance: .3f}')
        print(
            f'-Round time: {self.total_time - self.operation_time - self.pickup_time - self.place_time: .3f}, Round distance: '
            f'{self.total_distance - self.pickup_distance - self.place_distance: .3f}')

        print(f'-Round & place time per cycle: {(self.total_time - self.pickup_time - self.operation_time) * 1000.0 / (self.cycle_counter + 1e-10): .3f}, ', end='')
        print(f'-Round & place distance per cycle: {(self.total_distance - self.pickup_distance) / (self.cycle_counter + 1e-10): .3f}')

        minutes, seconds = int(self.total_time // 60), int(self.total_time) % 60
        millisecond = int((self.total_time - minutes * 60 - seconds) * 60)

        print(f'-Operation time: {self.operation_time: .3f}, ', end='')
        if minutes > 0:
            print(f'Total time:  {minutes: d} min {seconds} s {millisecond: 2d} ms ({self.total_time: .3f}s)')
        else:
            print(f'Total time:  {seconds} s {millisecond :2d} ms ({self.total_time :.3f}s)')
