{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_GHC -fno-warn-incomplete-patterns -fno-warn-name-shadowing #-}

module Bio.Sequence.Alignment.Internal.Matrix.Scoring where

import           Control.Applicative                  (liftA2)
import           Data.List                            (words)

import           Bio.Sequence.Alignment.Internal.Type

class ScoringMatrix a where
  scoring :: a -> Substitution Char

loadMatrix :: String -> [((Char, Char), Int)]
loadMatrix txt = concat table
  where f = liftA2 (||) null ((/= '#') . head)
        strip = reverse . dropWhile (== ' ') . reverse . dropWhile (== ' ')
        !txtlns = filter f (strip <$> lines txt)
        !letters = (map head . words . head) txtlns
        !table = (map (lineMap . words) . tail) txtlns
        lineMap (x:xs) = let !hx = head x
                             f (n, c) = ((hx, c), n)
                         in f <$> (read <$> xs) `zip` letters