# -*- coding: UTF-8 -*-
# Copyright 2020 by Kurt Rathjen. All Rights Reserved.
#
# This library is free software: you can redistribute it and/or modify it 
# under the terms of the GNU Lesser General Public License as published by 
# the Free Software Foundation, either version 3 of the License, or 
# (at your option) any later version. This library is distributed in the 
# hope that it will be useful, but WITHOUT ANY WARRANTY; without even the 
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
# See the GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.

import os
import logging

from studiolibrarymaya import baseitem

try:
    import mutils
    import maya.cmds
except ImportError as error:
    print(error)


logger = logging.getLogger(__name__)


def save(path, *args, **kwargs):
    """Convenience function for saving a MirrorItem."""
    MirrorItem(path).safeSave(*args, **kwargs)


def load(path, *args, **kwargs):
    """Convenience function for loading a MirrorItem."""
    MirrorItem(path).load(*args, **kwargs)


class MirrorItem(baseitem.BaseItem):

    NAME = u"镜像板"
    EXTENSION = ".mirror"
    ICON_PATH = os.path.join(os.path.dirname(__file__), "icons", "mirrortable.png")
    TRANSFER_CLASS = mutils.MirrorTable
    TRANSFER_BASENAME = "mirrortable.json"

    def __init__(self, *args, **kwargs):
        """
        :type args: list
        :type kwargs: dict
        """
        super(MirrorItem, self).__init__(*args, **kwargs)

        self._validatedObjects = []

    def loadSchema(self):
        """
        Get schema used to load the mirror table item.
        
        :rtype: list[dict]
        """
        schema = super(MirrorItem, self).loadSchema()

        mt = self.transferObject()

        schema.insert(2, {"name": u"左", "value": mt.leftSide()})
        schema.insert(3, {"name": u"右", "value": mt.rightSide()})

        schema.extend([
            {
                "name": "optionsGroup",
                "title": u"镜像选项",
                "type": "group",
                "order": 2,
            },
            {
                "name": "keysOption",
                "title": u"范围",
                "type": "radio",
                "value": "Selected Range",
                "items": [u"所有帧", u"选中帧"],
                "persistent": True,
            },
            {
                "name": "option",
                "title": u"范围",
                "type": "enum",
                "default": u"交换",
                "items": [u"交换", u"左到右", u"右到左"],
                "persistent": True
            },
        ])

        return schema

    def load(self, **kwargs):
        MIROPTION_MAPPING = {
        u"交换": "swap",
        u"左到右": "left to right",
        u"右到左": "right to left"
        }
        KEYSOPTION_MAPPING = {
        u"所有帧": "All Keys",
        u"选中帧": "Selected Range"
        }        
        """
        Load the current mirror table to the given objects.

        :type kwargs: dict
        """
        mt = mutils.MirrorTable.fromPath(self.path() + "/mirrortable.json")
        # 获取用户选择的选项，并将其转换为英文
        miroption = kwargs.get("option")
        if miroption in MIROPTION_MAPPING:
            miroption = MIROPTION_MAPPING[miroption]
        keysoption = kwargs.get(u"keysOption")
        if keysoption in KEYSOPTION_MAPPING:
            keysoption = KEYSOPTION_MAPPING[keysoption]            
        mt.load(
            objects=kwargs.get("objects"),
            namespaces=kwargs.get("namespaces"),
            option=miroption,
            keysOption=keysoption,
            time=kwargs.get("time")
        )

    def saveSchema(self):
        """
        Get the fields used to save the item.
        
        :rtype: list[dict]
        """
        return [
            {
                "name": "folder",
                "type": "path",
                "layout": "vertical",
                "visible": False,
            },
            {
                "name": "name",
                "title": u"名称",
                "type": "string",
                "layout": "vertical"
            },
            {
                "name": "mirrorPlane",
                "title": u"镜像平面",
                "type": "buttonGroup",
                "default": "YZ",
                "layout": "vertical",
                "items": ["YZ", "XY", "XZ"],
            },
            {
                "name": "leftSide",
                "title": u"左边(*_L)",
                "type": "string",
                "layout": "vertical",
                "menu": {
                    "name": "0"
                }
            },
            {
                "name": "rightSide",
                "title": u"右边(*_L)",
                "type": "string",
                "layout": "vertical",
                "menu": {
                    "name": "0"
                }
            },
            {
                "name": "comment",
                "title": u"备注",
                "type": "text",
                "layout": "vertical"
            },
            {
                "name": "objects",
                "type": "objects",
                "label": {
                    "visible": False
                }
            },
        ]

    def saveValidator(self, **kwargs):
        """
        The save validator is called when an input field has changed.
        
        :type kwargs: dict
        :rtype: list[dict] 
        """
        results = super(MirrorItem, self).saveValidator(**kwargs)

        objects = maya.cmds.ls(selection=True) or []

        dirty = kwargs.get("fieldChanged") in ["leftSide", "rightSide"]
        dirty = dirty or self._validatedObjects != objects

        if dirty:
            self._validatedObjects = objects

            leftSide = kwargs.get("leftSide", "")
            if not leftSide:
                leftSide = mutils.MirrorTable.findLeftSide(objects)

            rightSide = kwargs.get("rightSide", "")
            if not rightSide:
                rightSide = mutils.MirrorTable.findRightSide(objects)

            mt = mutils.MirrorTable.fromObjects(
                    [],
                    leftSide=leftSide,
                    rightSide=rightSide
            )

            results.extend([
                {
                    "name": "leftSide",
                    "value": leftSide,
                    "menu": {
                        "name": str(mt.leftCount(objects))
                    }
                },
                {
                    "name": "rightSide",
                    "value": rightSide,
                    "menu": {
                        "name": str(mt.rightCount(objects))
                    }
                },
            ])

        return results

    def save(self, objects, **kwargs):
        """
        Save the given objects to the item path on disc.

        :type objects: list[str]
        :type kwargs: dict
        """
        super(MirrorItem, self).save(**kwargs)

        # Save the mirror table to the given location
        mutils.saveMirrorTable(
            self.path() + "/mirrortable.json",
            objects,
            metadata={"description": kwargs.get("comment", "")},
            leftSide=kwargs.get("leftSide"),
            rightSide=kwargs.get("rightSide"),
            mirrorPlane=kwargs.get("mirrorPlane"),
        )
