module BioInf.Secondary.Draw.DotBracket where
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS
import qualified Data.Vector.Unboxed as V
import Text.Printf
import Prelude hiding (sequence)
import Biobase.Secondary
class DotBracketDraw a where
  
  
  draw :: PairAnno -> SequenceNumbering -> a -> String
  
  
  drawParts :: PairAnno -> SequenceNumbering -> a -> Parts
  
  drawPK :: PairAnno -> SequenceNumbering -> a -> String
data Parts = Parts
  { numbers :: Maybe String
  , sequence :: String
  , structure :: String
  , extended :: [String]
  }
instance DotBracketDraw (String,[ExtPairIdx]) where
  draw pa sn (seq,xs) = unlines $
    maybe [] (:[]) numbers ++
    [ sequence
    , structure
    ] ++ extended
    where
      Parts{..} = drawParts pa sn (seq,xs)
  drawParts pa sn (seq,xs) = Parts
    { numbers = if sn==Numbered then Just . take l . concat $ repeat ['0'..'9'] else Nothing
    , sequence = seq
    , structure = V.toList $ V.accum updateStructure (V.fromList $ replicate l '.') (map ((,'(').baseL) xs ++ map ((,')').baseR) xs)
    , extended = [ printf "  %4d %4d   %c-%c   %s" (baseL x) (baseR x) (seq!!baseL x) (seq!!baseR x) (show $ baseT x)
                 | x <- xs, pa == Always || pa == Required && baseT x /= cWW
                 ]
    } where
      l = length seq
      updateStructure cur new
        | cur == '.' = new
        | cur == new && cur == '(' = '<'
        | cur == new && cur == ')' = '>'
        | cur `elem` "()" && new `elem` "()" = 'X'
        | otherwise = '3' 
instance DotBracketDraw (String,[PairIdx]) where
  draw pa sn (seq,xs) = draw pa sn (seq,map (\x -> ((baseL x, baseR x), baseT x)) xs)
  drawParts pa sn (seq,xs) = drawParts pa sn (seq, map (\x -> ((baseL x, baseR x), baseT x)) xs)
instance DotBracketDraw (ByteString,[PairIdx]) where
  draw pa sn (seq,xs) = draw pa sn (BS.unpack seq,xs)
  drawParts pa sn (seq,xs) = drawParts pa sn (BS.unpack seq, xs)
instance DotBracketDraw (ByteString,[ExtPairIdx]) where
  draw pa sn (seq,xs) = draw pa sn (BS.unpack seq,xs)
  drawParts pa sn (seq,xs) = drawParts pa sn (BS.unpack seq, xs)
data PairAnno
  
  = Never
  
  
  | Required
  
  | Always
  deriving (Show,Read,Eq)
data SequenceNumbering
  = Numbered
  | NotNumbered
  deriving (Show,Read,Eq)