#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri May 27 13:10:59 2022

@author: elena
"""

import pandas as pd
import numpy as np
from .loggers import LoggingMixin
from django.conf import settings

class LinearAlignment(LoggingMixin):
    logging_name = "receipeServer.alignment"
    
    def __init__(self, logging_group, progress_callback=None):
        super().__init__()
        #self.logging_group = logging_group

        self.FMatrix = []
        self.distance = 0
        
        self.compareString = ''
        self.searchString = ''
        
        #self.charIndex = {'A':0, 'B':1, 'C':2, 'D':3, 'E':4, 'F':5, 'G':6, 'H':7, 'I':8,
        #                  'J': 9, 'K': 10, 'L':11, 'M':12, 'N':13, 'O':14, 'P':15, 'Q':16, 'R':17,
        #                  'S': 18, 'T': 19, 'U':20, 'V':21, 'W':22, 'X':23, 'Y':24, 'Z':25,
        #                  '1':26, '2': 27, '3': 28, '4':29, '5':30, '6':31, '7':32,
        #                  '8':33, '9':34, '0':35, ':':36, '.': 37, '!':38, ' ':39, '%':40}
        
        self.scoreMatrix = pd.read_csv(settings.BASE_DIR+'/receipe/score_matrix.csv',sep=';',index_col=0,header=0)
        self.scoreMatrix.fillna(0,inplace=True)
        
    def setStrings(self, compareString, searchString):
        self.FMatrix = []
        self.compareString = compareString
        self.searchString = searchString
        
    def scoring(self):
        #Zeilen
        compareStringSize = len(self.compareString)
        line = []
    
        for idx in range(0,compareStringSize + 1):
            line.append(-self.distance*idx)
        
        self.FMatrix.append(line)
    
        #Spalten
        for idy in range(1,len(self.searchString) + 1) :
            for idx in range(0, compareStringSize):
              if idx == 0:
                line[idx] = -self.distance*idy
              else:
                line[idx] = 0
            
            self.FMatrix.append(line)
        

    
        for idy in range(1, len(self.FMatrix)):
          for idx in range(1, len(self.FMatrix[0])):
            elements = np.array([])
           
            elements = np.append(elements,self.FMatrix[idy-1][idx-1] + self.scoreMatrix[self.searchString[idy-1]][self.compareString[idx-1]])
            elements = np.append(elements,self.FMatrix[idy][idx-1] - self.distance);
            elements = np.append(elements,self.FMatrix[idy-1][idx] - self.distance);
    
            biggest = np.max(elements)
            self.FMatrix[idy][idx] = biggest

    
        return self.FMatrix[len(self.FMatrix)-1][len(self.FMatrix[0])-1] / np.max([len(self.compareString),len(self.searchString)]) / 10
    
    def backTrace(self):
        if len(self.FMatrix) == 0:
            print('Run scoring before backTrace!')
            return 0
        alignmentA = "";
        alignmentB = "";

        idx = len(self.compareString) 
        idy = len(self.searchString) 

        while (idx > 0 or idy > 0) : 
          if (idx > 0) and (idy > 0) and (self.FMatrix[idy][idx] == self.FMatrix[idy-1][idx-1] + self.scoreMatrix[self.searchString[idy-1]][self.compareString[idx-1]]):
              alignmentA = alignmentA + self.compareString[idx-1]
              alignmentB = alignmentB + self.searchString[idy-1]
              idx = idx - 1
              idy = idy - 1
          
          elif (idx > 0) and (self.FMatrix[idy][idx-1] - self.distance) :
              alignmentA = alignmentA + self.compareString[idx-1]
              alignmentB = alignmentB + '-'
              idx = idx - 1
          
          else:
              alignmentA = alignmentA + '-'
              alignmentB = alignmentB + self.searchString[idy-1]
              idy = idy - 1
            
        
    
        alignmentA = alignmentA[::-1]
        alignmentB = alignmentB[::-1]
    
    
        return alignmentA,alignmentB    
        
