
define(['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {
    'use strict';

    var Utils = requtils.getUtils();

    /* Edge Class Begin */

    //var Edge = Renderer.Edge = Utils.inherit(Renderer._BaseRepresentation);
    var Edge = Utils.inherit(BaseRepresentation);

    _(Edge.prototype).extend({
        _init: function() {
            this.renderer.edge_layer.activate();
            this.type = "Edge";
            this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
            this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
            this.bundle = this.renderer.addToBundles(this);
            this.line = new paper.Path();
            this.line.add([0,0],[0,0],[0,0]);
            this.line.__representation = this;
            this.line.strokeWidth = this.options.edge_stroke_width;
            this.arrow = new paper.Path();
            this.arrow.add(
                    [ 0, 0 ],
                    [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
                    [ 0, this.options.edge_arrow_width ]
            );
            this.arrow.__representation = this;
            this.text = $('<div class="Rk-Label Rk-Edge-Label">').appendTo(this.renderer.labels_$);
            this.arrow_angle = 0;
            if (this.options.editor_mode) {
                var Renderer = requtils.getRenderer();
                this.normal_buttons = [
                                       new Renderer.EdgeEditButton(this.renderer, null),
                                       new Renderer.EdgeRemoveButton(this.renderer, null)
                                       ];
                this.pending_delete_buttons = [
                                               new Renderer.EdgeRevertButton(this.renderer, null)
                                               ];
                this.all_buttons = this.normal_buttons.concat(this.pending_delete_buttons);
                for (var i = 0; i < this.all_buttons.length; i++) {
                    this.all_buttons[i].source_representation = this;
                }
                this.active_buttons = [];
            } else {
                this.active_buttons = this.all_buttons = [];
            }

            if (this.renderer.minimap) {
                this.renderer.minimap.edge_layer.activate();
                this.minimap_line = new paper.Path();
                this.minimap_line.add([0,0],[0,0]);
                this.minimap_line.__representation = this.renderer.minimap.miniframe.__representation;
                this.minimap_line.strokeWidth = 1;
            }
        },
        redraw: function() {
            var from = this.model.get("from"),
            to = this.model.get("to");
            if (!from || !to) {
                return;
            }
            this.from_representation = this.renderer.getRepresentationByModel(from);
            this.to_representation = this.renderer.getRepresentationByModel(to);
            if (typeof this.from_representation === "undefined" || typeof this.to_representation === "undefined") {
                return;
            }
            var _p0a = this.from_representation.paper_coords,
            _p1a = this.to_representation.paper_coords,
            _v = _p1a.subtract(_p0a),
            _r = _v.length,
            _u = _v.divide(_r),
            _ortho = new paper.Point([- _u.y, _u.x]),
            _group_pos = this.bundle.getPosition(this),
            _delta = _ortho.multiply( this.options.edge_gap_in_bundles * _group_pos ),
            _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
            _p1b = _p1a.add(_delta), /* to differentiate bundled links */
            _a = _v.angle,
            _textdelta = _ortho.multiply(this.options.edge_label_distance),
            _handle = _v.divide(3),
            _color = this.model.get("color") || this.model.get("color") || (this.model.get("created_by") || Utils._USER_PLACEHOLDER(this.renkan)).get("color"),
            opacity = 1;

            if (this.model.get("delete_scheduled") || this.from_representation.model.get("delete_scheduled") || this.to_representation.model.get("delete_scheduled")) {
                opacity = 0.5;
                this.line.dashArray = [2, 2];
            } else {
                opacity = 1;
                this.line.dashArray = null;
            }

            var old_act_btn = this.active_buttons;

            this.active_buttons = this.model.get("delete_scheduled") ? this.pending_delete_buttons : this.normal_buttons;

            if (this.selected && this.renderer.isEditable() && old_act_btn !== this.active_buttons) {
                old_act_btn.forEach(function(b) {
                    b.hide();
                });
                this.active_buttons.forEach(function(b) {
                    b.show();
                });
            }

            this.paper_coords = _p0b.add(_p1b).divide(2);
            this.line.strokeColor = _color;
            this.line.opacity = opacity;
            this.line.segments[0].point = _p0a;
            this.line.segments[1].point = this.paper_coords;
            this.line.segments[1].handleIn = _handle.multiply(-1);
            this.line.segments[1].handleOut = _handle;
            this.line.segments[2].point = _p1a;
            this.arrow.rotate(_a - this.arrow_angle);
            this.arrow.fillColor = _color;
            this.arrow.opacity = opacity;
            this.arrow.position = this.paper_coords;
            this.arrow_angle = _a;
            if (_a > 90) {
                _a -= 180;
                _textdelta = _textdelta.multiply(-1);
            }
            if (_a < -90) {
                _a += 180;
                _textdelta = _textdelta.multiply(-1);
            }
            var _text = this.model.get("title") || this.renkan.translate(this.options.label_untitled_edges) || "";
            _text = Utils.shortenText(_text, this.options.node_label_max_length);
            this.text.text(_text);
            var _textpos = this.paper_coords.add(_textdelta);
            this.text.css({
                left: _textpos.x,
                top: _textpos.y,
                transform: "rotate(" + _a + "deg)",
                "-moz-transform": "rotate(" + _a + "deg)",
                "-webkit-transform": "rotate(" + _a + "deg)",
                opacity: opacity
            });
            this.text_angle = _a;

            var _pc = this.paper_coords;
            this.all_buttons.forEach(function(b) {
                b.moveTo(_pc);
            });

            if (this.renderer.minimap) {
                this.minimap_line.strokeColor = _color;
                this.minimap_line.segments[0].point = this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get("position")));
                this.minimap_line.segments[1].point = this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get("position")));
            }
        },
        openEditor: function() {
            this.renderer.removeRepresentationsOfType("editor");
            var _editor = this.renderer.addRepresentation("EdgeEditor",null);
            _editor.source_representation = this;
            _editor.draw();
        },
        select: function() {
            this.selected = true;
            this.line.strokeWidth = this.options.selected_edge_stroke_width;
            if (this.renderer.isEditable()) {
                this.active_buttons.forEach(function(b) {
                    b.show();
                });
            }
            if (!this.options.editor_mode) {
                this.openEditor();
            }
            this._super("select");
        },
        unselect: function(_newTarget) {
            if (!_newTarget || _newTarget.source_representation !== this) {
                this.selected = false;
                if (this.options.editor_mode) {
                    this.all_buttons.forEach(function(b) {
                        b.hide();
                    });
                }
                this.line.strokeWidth = this.options.edge_stroke_width;
                this._super("unselect");
            }
        },
        mousedown: function(_event, _isTouch) {
            if (_isTouch) {
                this.renderer.unselectAll();
                this.select();
            }
        },
        mouseup: function(_event, _isTouch) {
            if (!this.renkan.read_only && this.renderer.is_dragging) {
                this.from_representation.saveCoords();
                this.to_representation.saveCoords();
                this.from_representation.is_dragging = false;
                this.to_representation.is_dragging = false;
            } else {
                if (!_isTouch) {
                    this.openEditor();
                }
                this.model.trigger("clicked");
            }
            this.renderer.click_target = null;
            this.renderer.is_dragging = false;
        },
        paperShift: function(_delta) {
            if (this.options.editor_mode) {
                if (!this.options.read_only) {
                    this.from_representation.paperShift(_delta);
                    this.to_representation.paperShift(_delta);
                }
            } else {
                this.renderer.paperShift(_delta);
            }
        },
        destroy: function() {
            this._super("destroy");
            this.line.remove();
            this.arrow.remove();
            this.text.remove();
            if (this.renderer.minimap) {
                this.minimap_line.remove();
            }
            this.all_buttons.forEach(function(b) {
                b.destroy();
            });
            var _this = this;
            this.bundle.edges = _(this.bundle.edges).reject(function(_edge) {
                return _this === _edge;
            });
        }
    });

    return Edge;

});
