var angular = require('angular');
require('../index');
require('./CommonService');
require('kinetic');

var module = angular.module('commons.services.workflowstatus');

module.factory('WorkFlowStatusService', function($http) {
  return {
    queryFlowStatus: function(flowType, recordId) {
      return $http.get('/workflow/flowStatus?flowType=' + flowType + '&recordId=' + recordId).then(function(response) {
        return response.data;
      });
    }
  };
});

module.factory('WorkFlowStatus', function($toast, CommonService) {
  function WorkFlowStatus(config) {
    this.config = config;
    this.workflowData = {};
    this.nodes = {};
    this.texts = {};
    this.rects = [];
    this.lines = [];
    this.stage = {};
    this.nodeLayer = {};
  }

  WorkFlowStatus.prototype.setWorkflowData = function(data) {
    this.workflowData = data;
  };

  WorkFlowStatus.prototype.drawNode = function(nodeIndex, imageObj) {
      var node = this.workflowData.nodes[nodeIndex];
      var shape = new Kinetic.Image({
        x: node.x,
        y: node.y,
        id: node.id,
        offsetX: 25,
        offsetY: 25,
        image: imageObj[node.status]
      });

      this.nodes[node.id] = shape;
  };

  WorkFlowStatus.prototype.drawText = function(nodeIndex) {
    var node = this.workflowData.nodes[nodeIndex];
    var shape = this.nodes[node.id];
    var text = new Kinetic.Text({
      fill: 'green',
      text: node.name
    });
    function alertMessage() {
      if (node.message) {
        CommonService.showAlert(node.message, '流程记录');
      }
    }      
    shape.on('touchend', alertMessage);
    text.x(shape.x() - (text.getWidth() / 2));
    text.y(shape.y() + (text.getHeight() / 2) + 22);
    var rect = new Kinetic.Rect({
          width: text.getWidth() + 10,
          height: text.getHeight() + 8,
          fill: '#c8e0ff',
          strokeWidth: 0
        });

    rect.x(shape.x() - (text.getWidth() / 2) - 5);
    rect.y(shape.y() + (text.getHeight() / 2) + 18);      
    this.texts[node.id] = text;
    this.rects[node.id] = rect;
  };

  WorkFlowStatus.prototype.drawLine = function(lineIndex) {
    var line = this.workflowData.lines[lineIndex];
    if (line.start !== line.end) {
      var startNode = this.nodes[line.start];
      var endNode = this.nodes[line.end];
      var startX = startNode.x(),
        startY = startNode.y();
      var endX = endNode.x(),
        endY = endNode.y();
      var bezierLine = new Kinetic.Line({
        dashArray: [10, 10, 0, 10],
        strokeWidth: 3,
        stroke: 'black',
        lineCap: 'round',
        opacity: 0.5
      });
      bezierLine.setPoints([startX, startY, endX, endY]);
      this.lines.push(bezierLine);
    }
  };

  WorkFlowStatus.prototype.setNodeLayer = function() {     
    this.nodeLayer.clear();
    for (var j in this.lines) {
      this.nodeLayer.add(this.lines[j]);
    }
    for (var key in this.nodes) {
      this.nodeLayer.add(this.nodes[key]);
      this.nodeLayer.add(this.rects[key]);
      this.nodeLayer.add(this.texts[key]);
    }
  };

  WorkFlowStatus.prototype.draw = function(imageObj) {
    var maxWidth = 0;
    var maxHeight = 0;
    for (var i in this.workflowData.nodes) {
      var n = this.workflowData.nodes[i];
      maxWidth = Math.max(maxWidth, n.x);
      maxHeight = Math.max(maxHeight, n.y);
    }
    maxWidth = maxWidth + 40;
    maxHeight = maxHeight + 40;
    this.config.width = this.config.width || maxWidth;
    this.config.height = this.config.height || maxHeight;
    this.stage = new Kinetic.Stage({
      container: this.config.container,
      width: this.config.width,
      height: this.config.height+15
    });
    for (var nodeIndex in this.workflowData.nodes) {
      this.drawNode(nodeIndex, imageObj);
    }
    for (var lineIndex in this.workflowData.lines) {
      this.drawLine(lineIndex);
    }
    for (var textIndex in this.workflowData.nodes) {
      this.drawText(textIndex, imageObj);
    } 
    this.nodeLayer = new Kinetic.Layer();
    this.stage.add(this.nodeLayer);
    this.setNodeLayer();
    this.nodeLayer.draw();
  };
  return WorkFlowStatus;
});
