/**
 * @file bezier曲线拟合
 * @author mengke01(kekee000@gmail.com)
 */

define(
    function(require) {

        var fitCurve = require('graphics/image/contour/fitCurve');
        var fitBezier = require('graphics/image/contour/fitBezier');
        var lang = require('common/lang');

        /**
         * 计算bezier曲线B0参数
         *
         * @param {number} u t值
         * @return {number}
         */
        function B0(u) {
            var tmp = 1.0 - u;
            return (tmp * tmp * tmp);
        }

        /**
         * 计算bezier曲线B1参数
         *
         * @param {number} u t值
         * @return {number}
         */
        function B1(u) {
            var tmp = 1.0 - u;
            return (3 * u * (tmp * tmp));
        }

        /**
         * 计算bezier曲线B2参数
         *
         * @param {number} u t值
         * @return {number}
         */
        function B2(u) {
            var tmp = 1.0 - u;
            return (3 * u * u * tmp);
        }

        /**
         * 计算bezier曲线B3参数
         *
         * @param {number} u t值
         * @return {number}
         */
        function B3(u) {
            return (u * u * u);
        }

        var entry = {

            /**
             * 初始化
             */
            init: function () {

                var canvas = $('#canvas').get(0);
                var ctx = canvas.getContext('2d');
                var width = canvas.offsetWidth;
                var height = canvas.offsetHeight;

                var points = [{"x":50,"y":50},{"x":264,"y":354},{"x":451,"y":332},{"x":600,"y":60}];

                $(points).each(function(index, item) {
                    $('[data-index="'+index+'"]').css({
                        left: points[index].x,
                        top: points[index].y
                    })
                });

                var point;

                $('.point').on('mousedown', function(e) {
                    point = $(this);
                });

                $(document.body).on('mousemove', onMove);
                $(document.body).on('mouseup', function(e) {
                    onMove.call(this, e);
                    point = null;
                });

                function onMove(e) {
                    var px = e.pageX;
                    var py = e.pageY;
                    if(point) {
                        point.css({
                            left: px,
                            top: py
                        });
                        var p = points[+point.attr('data-index')];
                        p.x = px;
                        p.y = py;
                        draw();
                    }
                }

                function draw() {
                    ctx.clearRect(0, 0, width, height);

                    ctx.beginPath();
                    ctx.strokeStyle='gray';
                    ctx.moveTo(points[0].x, points[0].y);
                    ctx.bezierCurveTo(points[1].x,points[1].y,points[2].x,points[2].y,points[3].x,points[3].y);
                    ctx.stroke();

                    var curvePoints = [];
                    var count = 40;
                    var tSegment = 1 / count;
                    for (var i = 0; i <= count; i++) {
                        var t = tSegment * i;
                        curvePoints.push({
                            x: points[0].x * B0(t) + points[1].x * B1(t) + points[2].x * B2(t) + points[3].x * B3(t),
                            y: points[0].y * B0(t) + points[1].y * B1(t) + points[2].y * B2(t) + points[3].y * B3(t)
                        });
                    }

                    ctx.fillStyle='green';
                    for (var i = 0; i < count; i++) {
                        ctx.fillRect(curvePoints[i].x, curvePoints[i].y, 2, 2);
                    }

                    var result = fitCurve(lang.clone(curvePoints), 36);
                    result.unshift(points[0]);
                    console.log(result.length);

                    ctx.beginPath();
                    ctx.strokeStyle='blue';
                    //ctx.translate(0, 5);
                    ctx.moveTo(result[0].x, result[0].y);
                    for (var i = 1; i < result.length - 1; i+=3) {
                       ctx.bezierCurveTo(result[i].x, result[i].y, result[i + 1].x, result[i + 1].y, result[i + 2].x, result[i + 2].y);
                       ctx.moveTo(result[i + 2].x, result[i + 2].y);
                    }

                    ctx.stroke();

                    var bezierResult = fitBezier(lang.clone(curvePoints));
                    bezierResult.unshift(curvePoints[0]);
                    ctx.beginPath();
                    ctx.strokeStyle='yellow';
                    //ctx.translate(0, 5);
                    ctx.moveTo(bezierResult[0].x, bezierResult[0].y);
                    var last = bezierResult.length - 1;
                    console.log(bezierResult.length);
                    for (var i = 1; i < last; i+=2) {
                       ctx.quadraticCurveTo(bezierResult[i].x, bezierResult[i].y, bezierResult[i + 1].x, bezierResult[i + 1].y);
                       ctx.moveTo(bezierResult[i + 1].x, bezierResult[i + 1].y);
                    }

                    ctx.stroke();

                    //ctx.translate(0, -10);
                }

                draw();
            }
        };

        entry.init();

        return entry;
    }
);
