var raycaster, lastMouse;
var isClickDownOnModel;
var mouseCurrent;
//初始化数据
function initClipArgs() {
    raycaster = new THREE.Raycaster();
    lastMouse = new THREE.Vector2();
    initMoveClipPlaneArgs();
    initRotateClipPlaneArgs();
    document.addEventListener(OSHelper.touchStart, onMouseDown, false);
    document.addEventListener(OSHelper.touchMove, onMouseMove, false);
    EventCenter.addEventHandler('updateLastMousePos', updateMousePosition);
    mouseCurrent = new THREE.Vector2();
}

//鼠标点击事件
function onMouseDown(event) {
    if (!SpriteManager.allowClip) {
        return;
    }

    document.body.style.cursor = 'pointer';
    //重置旋转切割信息
    rotateStateReset();

    setRayCaster(event, cameraOrtho);
    if (SpriteManager.mouseDown(raycaster)) {
        return;
    }

    let activeMeshInfo = getActiveMesh(event);
    if (activeMeshInfo == undefined) {
        return;
    }

    ClipPlaneManager.meshIsActive();
    ClipPlaneManager.activeMeshInfo = activeMeshInfo;
    isClickDownOnModel = true;
    ClipPlaneManager.drawActiveMeshEdges();
    switch (SpriteManager.clipType) {
        case ClipType.DrawLine: {
            removeRotateInfo();
            startClipListener();
            break;
        }
        case ClipType.MoveClipPlane: {
            //move clip plane
            if (ClipPlaneManager.activeMeshInfo.isCubeMesh()) {
                ClipPlaneManager.generateCubeFaceClipPlane();
            }

            ClipPlaneManager.setMaxForwardDistance();
            addRotateInfo();
            EventCenter.emit("updateLastMousePos", event);
            startClipListener();
            break;
        }
    }

}

function onMouseMove(event) {
    if (isClickDownOnModel && ClipPlaneManager.activeMeshInfo != undefined) {
        switch (SpriteManager.clipType) {
            case ClipType.DrawLine: {
                setRayCaster(event, camera);
                drawClipLine(raycaster);
                break;
            }
            case ClipType.MoveClipPlane: {
                moveClipPlane(event, lastMouse);
                break;
            }
        }
    }
    else if (OSHelper.isPC) {
        setRayCaster(event, cameraOrtho);
        SpriteManager.mouseMove(raycaster);
    }
}

function onMouseUp() {
    if (ClipPlaneManager.activeMeshInfo != undefined) {
        switch (SpriteManager.clipType) {
            case ClipType.DrawLine:
                {
                    ClipPlaneManager.generateClipPlane();
                    break;
                }
            case ClipType.MoveClipPlane:
                {
                    if (ClipPlaneManager.activeMeshInfo.isMovePlane()) {
                        ClipPlaneManager.activeMeshInfo.resetPlaneInfo();
                        if (ClipPlaneManager.isActivePlaneCompleteClipped()) {
                            ClipPlaneManager.removeClipPlane();
                            removeRotateInfo();
                        }
                    }
                    break;
                }
        }
    }
    removeClipListener();
}

function startClipListener() {
    orbitCtl.enableZoom = false;
    orbitCtl.enableRotate = false;
    document.addEventListener(OSHelper.touchEnd, onMouseUp, false);
}

function removeClipListener() {
    orbitCtl.enableZoom = true;
    orbitCtl.enableRotate = true;
    isClickDownOnModel = false;
    document.body.style.cursor = 'default';
    document.removeEventListener(OSHelper.touchEnd, onMouseUp, false);
}

//记录鼠标位置
function updateMousePosition(event) {
    lastMouse.x = OSHelper.clientX(event);
    lastMouse.y = OSHelper.clientY(event);
}

//检查点是否存在
function pointIsDuplicate(points, point) {
    let index = points.findIndex(n => n.xyzFixedEq(point, 7));
    if (index > -1) {
        return true;
    }
    return false;
}

//判断鼠标是否点在模型上
function getActiveMesh(event) {
    //判断鼠标点到模型上并获取mesh信息
    setRayCaster(event, camera);
    let meshInfo = ClipPlaneManager.getActiveMeshInfo(raycaster);
    if (meshInfo != undefined) {
        if(isClickOnVisibleRegion(meshInfo))
        {
           return meshInfo;
        }
    }

    return undefined;

    //检查鼠标点击的点是否在切掉(看不见)的区域
    function isClickOnVisibleRegion(meshInfo) {
        let clipPlanes = meshInfo.getClipPlanes();
        let projectPoint = new THREE.Vector3();
        if (clipPlanes != null) {
            for (let cursor = 0; cursor < clipPlanes.length; cursor++) {
                clipPlanes[cursor].projectPoint(meshInfo.Point, projectPoint);
                if (meshInfo.Point.xyzFixedEq(projectPoint, 3))
                    continue;
                let projectDirection = meshInfo.Point.clone().sub(projectPoint);
                if (projectDirection.dot(clipPlanes[cursor].normal) < 0) {
                    return false;
                }
            }
        }
        return true;
    }
}

//设置相机指向鼠标的射线
function setRayCaster(event, camera) {
    mouseCurrent.set((OSHelper.clientX(event) / window.innerWidth) * 2 - 1,
        1 - (OSHelper.clientY(event) / window.innerHeight) * 2);
    raycaster.setFromCamera(mouseCurrent, camera);
}

function drawClipLine(raycaster) {
    let intersectObject = ClipPlaneManager.activeMeshInfo.getRaycasterFirstIntersectObject(raycaster);
    if (intersectObject != undefined) {
        if (isInvalidMove(intersectObject)) {
            return;
        }

        LinesDrawingManager.showClipLine(ClipPlaneManager.activeMeshInfo.Point,  intersectObject.point);
    }

    //判断鼠标是否移出了切线所在面的可见区域
    function isInvalidMove(intersectObject) {
        let planes = [];
        if (ClipPlaneManager.activeMeshInfo.isCubeMesh()) {
            if (ClipPlaneManager.activeMeshInfo.Mesh.face.materialIndex != intersectObject.face.materialIndex)
                return true;
            planes = intersectObject.object.material[0].clippingPlanes;
        } else {
            planes = intersectObject.object.material.clippingPlanes;
        }

        if (planes.length > 0) {
            let line = new THREE.Line3(ClipPlaneManager.activeMeshInfo.Point, intersectObject.point);
            for (let cursor = 0; cursor < planes.length; cursor++) {
                if (planes[cursor].intersectsLine(line)) {
                    return true;
                }
            }
        }
        return false;
    }
}