public GeneNode(GeneNode prev, char x, char y, int cost)
 {
     this.Prev = prev;
     this.X    = x.ToString();
     this.Y    = y.ToString();
     this.Cost = cost;
 }
        private GeneNode GetSmallest(GeneNode a, GeneNode b, GeneNode c)
        {
            var smallest = a;

            if (b.Cost < smallest.Cost)
            {
                smallest = b;
            }
            if (c.Cost < smallest.Cost)
            {
                smallest = c;
            }
            return(smallest);
        }
        public GeneNode Align(GeneSequence sequenceA, GeneSequence sequenceB, ResultTable resultTableSoFar, int rowInTable, int columnInTable)
        {
            // Check for equal alignment
            if (rowInTable == columnInTable)
            {
                return(new GeneNode(null, '0', '0', 0));
            }

            // Linear space requirement
            var resultSet1 = new List <GeneNode>(); // Prev Row
            var resultSet2 = new List <GeneNode>(); // Current Row

            // New Sequences
            string seqA = "0" + sequenceA.Sequence;
            string seqB = "0" + sequenceB.Sequence;

            // Clean up the length to cap at 5000
            int seqALength = seqA.Length;
            int seqBLength = seqB.Length;

            if (seqA.Length > MaxCharactersToAlign + 1)
            {
                seqALength = MaxCharactersToAlign + 1;
            }
            if (seqB.Length > MaxCharactersToAlign + 1)
            {
                seqBLength = MaxCharactersToAlign + 1;
            }

            // Core alignment algorithm
            for (int i = 0; i < seqALength; i++)
            {
                for (int j = 0; j < seqBLength; j++)
                {
                    GeneNode acc = null;
                    // Starting position
                    if (i == 0 && j == 0)
                    {
                        acc = new GeneNode(null, '0', '0', 0);
                    }
                    // Edge case
                    else if (i == 0 && j > 0)
                    {
                        // Get the node from the left cell, and add as indel
                        acc = new GeneNode(resultSet2[j - 1], '-', seqB[j], (resultSet2[j - 1].Cost + indel));
                    }
                    // Edge case
                    else if (i > 0 && j == 0)
                    {
                        // Get the node from the top cell, and add as indel
                        acc = new GeneNode(resultSet1[j], seqA[i], '-', (resultSet1[j].Cost + indel));
                    }

                    // Match Case
                    else if ((i > 0 && j > 0) && (seqA[i] == seqB[j]))
                    {
                        // Match or indel
                        var top  = new GeneNode(resultSet1[j], seqA[i], '-', (resultSet1[j].Cost + indel));
                        var left = new GeneNode(resultSet2[j - 1], '-', seqB[j], (resultSet2[j - 1].Cost + indel));
                        var diag = new GeneNode(resultSet1[j - 1], seqA[i], seqB[j], (resultSet1[j - 1].Cost + match));
                        // Get node neighbor with smallest cost in order of: left, top, diag
                        acc = GetSmallest(left, top, diag);
                    }

                    // Subsitution Case
                    else if ((i > 0 && j > 0) && (seqA[i] != seqB[j]))
                    {
                        // Sub or indel
                        var top  = new GeneNode(resultSet1[j], seqA[i], '-', (resultSet1[j].Cost + indel));
                        var left = new GeneNode(resultSet2[j - 1], '-', seqB[j], (resultSet2[j - 1].Cost + indel));
                        var diag = new GeneNode(resultSet1[j - 1], seqA[i], seqB[j], (resultSet1[j - 1].Cost + sub));
                        // Get node neighbor with smallest cost in order of: left, top, diag
                        acc = GetSmallest(left, top, diag);
                    }
                    // Add to lower row (current row) results
                    resultSet2.Add(acc);
                }

                // Make lower row the new upper row and clear the old lower row
                resultSet1 = resultSet2;
                resultSet2 = new List <GeneNode>();
            }
            // return the node at furthest (col, row) from origin
            return(resultSet1[resultSet1.Count - 1]);
        }