# The Nexus software is licensed under the BSD 2-Clause license.
#
# You should have recieved a copy of this license with the software.
# If you did not, you can find one at the following link.
#
# http://opensource.org/licenses/bsd-license.php


import sys
from reqs.twisted.internet import reactor
from core.plugins import ProtocolPlugin
from core.decorators import *
from core.constants import *

class BsavePlugin(ProtocolPlugin):
    
    commands = {
        "mirror": "commandMirror",
        "scaleup": "commandScaleUp",
        "scale": "commandScaleUp",
        "copy": "commandSave",
        "paste": "commandLoad",
        "pasta": "commandLoad",
        "rotate": "commandRotate",
        "xzrotate": "commandRotatexz",
        "xyrotate": "commandRotatexy",
        "yzrotate": "commandRotateyz",
    }

    @build_list
    @builder_only
    def commandMirror(self, parts, fromloc, overriderank):
        "/mirror axis - Op\nMirrors your copy across axis."
        if len(parts) != 2:
            self.client.sendServerMessage("Please include an axis and only an axis.")
        else:
            tempblocks = set()
            xmax = ymax = zmax = 0
            try:
                for x, y, z, block in self.client.bsaved_blocks:
                    if x > xmax:
                        xmax = x
                    if y > ymax:
                        ymax = y
                    if z > zmax:
                        zmax = z
            except:
                self.client.sendServerMessage("You haven't used /copy yet.")
                return
            for x, y, z, block in self.client.bsaved_blocks:
                if parts[1] == "x":
                    tempblocks.add(((x*-1)+xmax, y, z, block))
                elif parts[1] == "y":
                    tempblocks.add((x, (y*-1)+ymax, z, block))
                elif parts[1] == "z":
                    tempblocks.add((x, y, (z*-1)+zmax, block))
                else:
                    self.client.sendServerMessage("You must enter either x, y, or z.")
            self.client.bsaved_blocks = tempblocks
            if fromloc == "user":
                self.client.sendServerMessage("Your mirror just completed.")

    @build_list
    @builder_only
    def commandScaleUp(self, parts, fromloc, overriderank):
        "/scaleup factor - Op\nAliases: scale\nScales your copy by a given factor."
        if len(parts) < 2:
            self.client.sendServerMessage("You must give number input.")
        try:
            factor = int(parts[1])
        except ValueError:
            self.client.sendServerMessage("Factor must be an integer!")
            return
        if (factor < 2):
            self.client.sendServerMessage("Factor must be non-zero positive and not one(1)!")
        tempblocks = set()
        ymax = zmax = 0
        try:
            for x, y, z, block in self.client.bsaved_blocks:
                if y > ymax:
                    ymax = y
                if z > zmax:
                    zmax = z
        except:
            self.client.sendServerMessage("You haven't used /copy yet.")
            return
        for x, y, z, block in self.client.bsaved_blocks:
            for x2 in range(0, factor):
                for y2 in range(0, factor):
                    for z2 in range(0, factor):
                        tempblocks.add((((x*factor)-(x2-(factor-1))),((y*factor)-(y2-(factor-1))),((z*factor)-(z2-(factor-1))),block))
        self.client.bsaved_blocks = tempblocks
        if fromloc=="user":
            self.client.sendServerMessage("Your scaleup just completed.")
    
    @build_list
    @builder_only
    def commandLoad(self, parts, fromloc, overriderank):
        "/paste [x y z] - Builder\nAliases: pasta\nRestore blocks saved earlier using /copy"
        if len(parts) < 4 and len(parts) != 1:
            self.client.sendServerMessage("Please enter coordinates.")
        else:
            if len(parts) == 1:
                try:
                    x, y, z = self.client.last_block_changes[0]
                except IndexError:
                    self.client.sendServerMessage("You have not placed a marker yet.")
                    return
            else:
                try:
                    x = int(parts[1])
                    y = int(parts[2])
                    z = int(parts[3])
                except ValueError:
                    self.client.sendServerMessage("All coordinate parameters must be integers.")
                    return
            # Check whether we have anything saved
            try:
                num_saved = len(self.client.bsaved_blocks)
                if fromloc == "user":
                    self.client.sendServerMessage("Loading %d blocks..." % num_saved)
            except AttributeError:
                self.client.sendServerMessage("Please /copy something first.")
                return
            # Draw all the blocks on, I guess
            # We use a generator so we can slowly release the blocks
            # We also keep world as a local so they can't change worlds and affect the new one
            world = self.client.world