Code/Dependencies/DotNetGraph/Core/DotEdge.cs
using System.Linq;
using System.Threading.Tasks;
using Nodebox.Dependencies.DotNetGraph.Attributes;
using Nodebox.Dependencies.DotNetGraph.Compilation;
using Nodebox.Dependencies.DotNetGraph.Exceptions;

namespace Nodebox.Dependencies.DotNetGraph.Core {
    public class DotEdge : DotElement {
        public DotIdentifier Source { get; set; }

        public DotIdentifier Destination { get; set; }

        public DotColorAttribute Color {
            get => GetAttributeOrDefault<DotColorAttribute>("color");
            set => SetAttribute("color", value);
        }

        public DotEdgeStyleAttribute Style {
            get => GetAttributeOrDefault<DotEdgeStyleAttribute>("style");
            set => SetAttribute("style", value);
        }

        public DotDoubleAttribute PenWidth {
            get => GetAttribute<DotDoubleAttribute>("penwidth");
            set => SetAttribute("penwidth", value);
        }

        public DotEdgeArrowTypeAttribute ArrowHead {
            get => GetAttribute<DotEdgeArrowTypeAttribute>("arrowhead");
            set => SetAttribute("arrowhead", value);
        }

        public DotEdgeArrowTypeAttribute ArrowTail {
            get => GetAttribute<DotEdgeArrowTypeAttribute>("arrowtail");
            set => SetAttribute("arrowtail", value);
        }

        public DotPointAttribute Pos {
            get => GetAttribute<DotPointAttribute>("pos");
            set => SetAttribute("pos", value);
        }

        public override async Task CompileAsync(CompilationContext context) {
            if (Source is null || Destination is null)
                throw new CompilationException("Can't compile edge with null Source and/or Destination");

            await context.WriteIndentationAsync();
            await Source.CompileAsync(context);
            await context.WriteAsync($" {(context.DirectedGraph ? "->" : "--")} ");
            await Destination.CompileAsync(context);
            if (Attributes.Any()) {
                await context.WriteLineAsync(" [");
                context.IndentationLevel++;
                await CompileAttributesAsync(context);
                context.IndentationLevel--;
                await context.WriteIndentationAsync();
                await context.WriteLineAsync("]");
            } else {
                await context.WriteLineAsync();
            }
        }
    }
}