/* <copyright>
This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
(c) Copyright 2011 Motorola Mobility, Inc.  All Rights Reserved.
</copyright> */

var Montage = require("montage/core/core").Montage,
    Component = require("montage/ui/component").Component;

exports.ThreeD = Montage.create(Component, {

    inGlobalMode: {
        value: false
    },

    // TODO - booleans not working with boundValueMutator when bound to selectedIndex, so using index
    // 0 = local; 1 = global
    _axisMode: {
        value: 0
    },

    axisMode: {
        get: function() {
            return this._axisMode;
        },
        set: function(value) {
            this._axisMode = value;
            
            if(value === 0) {
                this.inGlobalMode = false;
                this.x3D = 0;
                this.y3D = 0;
                this.z3D = 0;

                this.xAngle = 0;
                this.yAngle = 0;
                this.zAngle = 0;
            } else {
                this.inGlobalMode = true;
                var item = this.item;
                if(item) {
                    this.x3D = item.elementModel.props3D.x3D;
                    this.y3D = item.elementModel.props3D.y3D;
                    this.z3D = item.elementModel.props3D.z3D;

                    this.xAngle = item.elementModel.props3D.xAngle;
                    this.yAngle = item.elementModel.props3D.yAngle;
                    this.zAngle = item.elementModel.props3D.zAngle;
                }
            }
        }
    },

    x3DControl: {
        value: null,
        serializable: true
    },

    y3DControl: {
        value: null,
        serializable: true
    },

    z3DControl: {
        value: null,
        serializable: true
    },

    x3DLabel: {
        value: null,
        serializable: true
    },

    y3DLabel: {
        value: null,
        serializable: true
    },

    z3DLabel: {
        value: null,
        serializable: true
    },

    xAngleControl: {
        value: null,
        serializable: true
    },

    yAngleControl: {
        value: null,
        serializable: true
    },

    zAngleControl: {
        value: null,
        serializable: true
    },

    axisModeGroupControl: {
        value: null,
        serializable: true
    },

    flattenControl: {
        value: null,
        serializable: true
    },

    x3D: {
        value: 0
    },

    y3D: {
        value: 0
    },

    z3D: {
        value: 0
    },

    xAngle: {
        value: 0
    },

    yAngle: {
        value: 0
    },

    zAngle: {
        value: 0
    },

    flatten: {
        value: false
    },

    _disableTranslation: {
        value: true
    },

    disableTranslation: {
        get: function () {
            return this._disableTranslation;
        },
        set: function (value) {
            if(value !== this._disableTranslation) {
                this._disableTranslation  = value;
                this.needsDraw = true;
            }
        }
    },

    item: {
        value: null
    },

    _curMat: {
        value: null
    },

    _curProp: {
        value: null
    },

    _transformCtr: {
        value: null
    },

    handleAction: {
        value: function(event) {
            if(event.currentTarget.identifier === "flatten") {
                this.application.ninja.elementMediator.setProperty([this.item], "-webkit-transform-style",
                                                                    event.currentTarget.checked ? ["flat"] : ["preserve-3d"]);
            }
        }
    },

    handleChange: {
        value: function(event) {
            if(event.wasSetByCode) {
                return;
            }

            this.apply3DProperties(event.currentTarget.identifier, event.currentTarget, this.item, this.inGlobalMode, false);

            this._curMat = null;
            this._curProp = null;
        }
    },

    handleChanging: {
        value: function(event) {
            if(event.wasSetByCode) {
                return;
            }

            this.apply3DProperties(event.currentTarget.identifier, event.currentTarget, this.item, this.inGlobalMode, true);
        }
    },

    apply3DProperties : {
        value : function(prop, value, item, inGlobalMode, isChanging){
            if(!this._curMat) {
                this._curMat = this.application.ninja.elementMediator.getMatrix(item);
//                this._transformCtr = item.elementModel.props3D.m_transformCtr || [0,0,0];
                // TODO - Always use the center for now until we support multiple selections
                this._transformCtr = [0,0,0];
                if(inGlobalMode) {
                    this._transformCtr = MathUtils.transformPoint(this._transformCtr, this._curMat);
                }
            }

            var curMat = this._curMat,
                delta = value.value,
                isRotating = false,
                xFormMat = Matrix.I(4),
                tMat = Matrix.I(4),
                mat = [];
            if(inGlobalMode) {

                if(!this._curProp) {
                    this._curProp = this.application.ninja.elementMediator.get3DProperty(item, prop);
                }

                delta -= this._curProp;
            }

            switch (prop)
            {
                case "xAngle":
                    xFormMat = Matrix.RotationX(MathUtils.DEG_TO_RAD * delta);
                    isRotating = true;
                    break;
                case "yAngle":
                    xFormMat = Matrix.RotationY(MathUtils.DEG_TO_RAD * delta);
                    isRotating = true;
                    break;
                case "zAngle":
                    xFormMat = Matrix.RotationZ(MathUtils.DEG_TO_RAD * delta);
                    isRotating = true;
                    break;
                case "x3D":
                    xFormMat[12] = delta;
                    break;
                case "y3D":
                    xFormMat[13] = delta;
                    break;
                case "z3D":
                    xFormMat[14] = delta;
                    break;
            }

            if(inGlobalMode) {

                if(isRotating) {

                    // pre-translate by the transformation center
                    tMat[12] = this._transformCtr[0];
                    tMat[13] = this._transformCtr[1];
                    tMat[14] = this._transformCtr[2];

                    glmat4.multiply(tMat, xFormMat, mat);

                    // translate back
                    tMat[12] = -this._transformCtr[0];
                    tMat[13] = -this._transformCtr[1];
                    tMat[14] = -this._transformCtr[2];

                    glmat4.multiply(mat, tMat, mat);
                    glmat4.multiply(mat, curMat, mat);
                } else {
                    glmat4.multiply(xFormMat, curMat, mat);
                }
            } else {
                if(isRotating) {
                    tMat[12] = this._transformCtr[0];
                    tMat[13] = this._transformCtr[1];
                    tMat[14] = this._transformCtr[2];

                    glmat4.multiply(curMat, tMat, mat);

                    // translate back
                    tMat[12] = -this._transformCtr[0];
                    tMat[13] = -this._transformCtr[1];
                    tMat[14] = -this._transformCtr[2];

                    glmat4.multiply(mat, xFormMat, mat);
                    glmat4.multiply(mat, tMat, mat);
                } else {
                    glmat4.multiply(curMat, xFormMat, mat);
                }
            }

            if(isChanging) {
                this.application.ninja.elementMediator.setMatrix(item, mat, true);
            } else {
                this.application.ninja.elementMediator.setMatrix(item, mat, false);

                if(!inGlobalMode) {
                    value.value = 0;
                }
            }
        }
    },

    _currentDocument: {
        value : null
    },

    currentDocument : {
        get : function() {
            return this._currentDocument;
        },
        set : function(value) {
            if (value === this._currentDocument) {
                return;
            }

            this._currentDocument = value;

            if(this._currentDocument && this._currentDocument.currentView === "design") {
                // Save a reference of the pi inside the document view to be able to clear
                Object.defineBinding(this, "item", {
                    boundObject: this,
                    boundObjectPropertyPath: "application.ninja.selectedElements",
                    boundValueMutator: this._getSelectedItem,
                    oneway: true
                });
            }
        }
    },

    templateDidLoad : {
        value: function() {
            Object.defineBinding(this, "axisMode", {
                boundObject: this.axisModeGroupControl,
                boundObjectPropertyPath: "selectedIndex",
                oneway: false
            });
        }
    },

    _getSelectedItem: {
        value: function(els) {
            if(els.length) {
                return els[0];
            } else {
                return this.boundObject.application.ninja.currentDocument.model.documentRoot;
            }
        }
    },

    draw: {
        value: function() {
            if(this._disableTranslation) {
                this.x3D = 0;
                this.x3DControl.enabled = false;
                this.y3D = 0;
                this.y3DControl.enabled = false;
                this.z3D = 0;
                this.z3DControl.enabled = false;

                this.x3DLabel.classList.add("disabled");
                this.y3DLabel.classList.add("disabled");
                this.z3DLabel.classList.add("disabled");
            } else {
                this.x3DControl.enabled = true;
                this.y3DControl.enabled = true;
                this.z3DControl.enabled = true;
                this.x3DLabel.classList.remove("disabled");
                this.y3DLabel.classList.remove("disabled");
                this.z3DLabel.classList.remove("disabled");
            }
        }
    }

});