// Generated by CoffeeScript 1.4.0
(function() {
  var EdgeDrawer, StateDrawer, drawSearchProblem, exports,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  StateDrawer = (function() {

    function StateDrawer(paper, display, state, x, y, opts) {
      var _ref;
      this.paper = paper;
      this.display = display;
      this.state = state;
      this.x = x;
      this.y = y;
      if (opts == null) {
        opts = {};
      }
      this.unHighlight = __bind(this.unHighlight, this);

      this.highlight = __bind(this.highlight, this);

      this.select = __bind(this.select, this);

      this.editable = (_ref = opts.editable) != null ? _ref : false;
      this.selected = opts.selected;
      this.green = '#0c0';
      this.red = '#c03';
      this.blue = '#00f';
      this.yellow = '#d4c84a';
      this.white = '#fff';
    }

    StateDrawer.prototype.draw = function() {
      this.makeDrawing();
      this.display.updateValue(this.state, this.selected);
      this.validate();
      return this.setCallbacks();
    };

    StateDrawer.prototype.setCallbacks = function() {
      if (this.editable) {
        $(this.drawing.node).mouseover(this.highlight);
        $(this.text.node).mouseover(this.highlight);
        $(this.drawing.node).mouseout(this.unHighlight);
        $(this.text.node).click(this.select);
        return $(this.drawing.node).click(this.select);
      }
    };

    StateDrawer.prototype.setEditable = function() {
      if (!this.editable) {
        this.editable = true;
        $(this.drawing.node).mouseover(this.highlight);
        $(this.text.node).mouseover(this.highlight);
        $(this.drawing.node).mouseout(this.unHighlight);
        $(this.text.node).click(this.select);
        return $(this.drawing.node).click(this.select);
      }
    };

    StateDrawer.prototype.setUneditable = function() {
      if (this.editable) {
        this.editable = false;
        $(this.drawing.node).unbind('mouseover');
        $(this.text.node).unbind('mouseover');
        $(this.drawing.node).unbind('mouseout');
        $(this.text.node).unbind('click');
        return $(this.drawing.node).unbind('click');
      }
    };

    StateDrawer.prototype.loadValue = function() {
      this.selected = this.display.getValue(this.state);
      return this.validate();
    };

    StateDrawer.prototype.makeDrawing = function() {
      this.drawing = this.paper.circle(this.x, this.y, 16);
      return this.text = this.paper.text(this.x, this.y, this.state);
    };

    StateDrawer.prototype.select = function() {
      this.selected = !this.selected;
      this.display.updateValue(this.state, this.selected);
      return this.validate();
    };

    StateDrawer.prototype.validate = function() {
      this.status = this.display.partStatus(this.state, this.selected);
      return this.updateColor();
    };

    StateDrawer.prototype.highlight = function(event) {
      return this.drawing.attr({
        stroke: this.yellow,
        'stroke-width': 3
      });
    };

    StateDrawer.prototype.unHighlight = function(event) {
      return this.updateColor();
    };

    StateDrawer.prototype.updateColor = function() {
      switch (this.status) {
        case "unknown":
          this.drawing.attr({
            fill: this.white,
            stroke: this.blue,
            'stroke-width': 2,
            'stroke-dasharray': ""
          });
          break;
        case "correct":
          this.drawing.attr({
            stroke: this.green,
            fill: '#fff',
            'stroke-width': 3,
            'stroke-dasharray': ""
          });
          break;
        case "incorrect":
          this.drawing.attr({
            stroke: this.red,
            fill: '#fff',
            'stroke-width': 2,
            'stroke-dasharray': "."
          });
      }
      if (this.selected) {
        return this.drawing.attr({
          fill: "#bcd"
        });
      } else {
        return this.drawing.attr({
          fill: "#fff"
        });
      }
    };

    return StateDrawer;

  })();

  EdgeDrawer = (function() {

    function EdgeDrawer(paper, display, pathLength, path, arrow) {
      this.paper = paper;
      this.display = display;
      this.pathLength = pathLength;
      this.path = path;
      this.arrow = arrow;
    }

    EdgeDrawer.prototype.draw = function() {
      var bezierPath, segmentIndex, _i, _ref;
      bezierPath = "";
      for (segmentIndex = _i = 0, _ref = Math.floor(this.pathLength / 3); 0 <= _ref ? _i < _ref : _i > _ref; segmentIndex = 0 <= _ref ? ++_i : --_i) {
        bezierPath += this.getBezierSegment(this.path[segmentIndex * 3], this.path[segmentIndex * 3 + 1], this.path[segmentIndex * 3 + 2], this.path[segmentIndex * 3 + 3]);
      }
      this.pathDrawing = this.paper.path(bezierPath);
      return this.drawArrow();
    };

    EdgeDrawer.prototype.getBezierSegment = function(point1, point2, point3, point4) {
      var pathString;
      pathString = "";
      pathString += "M " + point1[0] + "," + point1[1] + " ";
      pathString += "C " + point2[0] + "," + point2[1] + " ";
      pathString += "" + point3[0] + "," + point3[1] + " ";
      pathString += "" + point4[0] + "," + point4[1];
      return pathString;
    };

    EdgeDrawer.prototype.drawArrow = function() {
      var pathString;
      pathString = "";
      pathString += "M " + this.arrow[0][0] + "," + this.arrow[0][1] + " ";
      pathString += "L " + this.arrow[1][0] + "," + this.arrow[1][1] + " ";
      pathString += "L " + this.arrow[2][0] + "," + this.arrow[2][1] + " ";
      pathString += "L " + this.arrow[0][0] + "," + this.arrow[0][1] + " ";
      return this.arrowDrawing = this.paper.path(pathString).attr('fill', 'black');
    };

    return EdgeDrawer;

  })();

  drawSearchProblem = function(paper, display, searchProblem, height) {
    var arrow, edge, edgeDrawings, opts, path, pathData, pathLength, point, state, stateDrawings, x, y, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2;
    stateDrawings = {};
    edgeDrawings = [];
    _ref = searchProblem.states;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      state = _ref[_i];
      x = searchProblem.statePositions[state][0];
      y = height - searchProblem.statePositions[state][1];
      opts = {
        selected: (_ref1 = display.newSubmission[state]) != null ? _ref1 : false,
        editable: display.editable
      };
      stateDrawings[state] = new StateDrawer(paper, display, state, x, y, opts);
    }
    _ref2 = searchProblem.edgeData;
    for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
      edge = _ref2[_j];
      pathData = edge[1][0];
      pathLength = pathData[0];
      path = pathData[1];
      arrow = edge[1][1];
      for (_k = 0, _len2 = path.length; _k < _len2; _k++) {
        point = path[_k];
        point[1] = height - point[1];
      }
      for (_l = 0, _len3 = arrow.length; _l < _len3; _l++) {
        point = arrow[_l];
        point[1] = height - point[1];
      }
      edgeDrawings.push(new EdgeDrawer(paper, display, pathLength, path, arrow));
    }
    return [stateDrawings, edgeDrawings];
  };

  exports = typeof root !== "undefined" && root !== null ? root : this;

  exports.StateDrawer = StateDrawer;

  exports.EdgeDrawer = EdgeDrawer;

  exports.drawSearchProblem = drawSearchProblem;

}).call(this);
