
"""
    landscape_functions
    ~~~~~~~~~~~~~~~~~~~

    Wrapper for all landscape analysis functions.

    :author: Fahad Khalid
    :license: MIT, see LICENSE for more details.
"""

import igraph

from peak_functions import PeakAnalyzer
from path_functions import PathAnalyzer
from epistasis_functions import EpistasisAnalyzer
from genonets_utils import Utils


class Landscape :
    # Constructor
    def __init__(self, network, netUtils, seqToEscrDict, delta, bitManip) :
        # Store reference to the network object
        self.network = network

        # Store reference to the netUtils object
        self.netUtils = netUtils

        # Create the peak analyzer
        self.peakAnalyzer = PeakAnalyzer(network, netUtils, delta)

        # Create the path analyzer
        self.pathAnalyzer = PathAnalyzer(network, netUtils, delta)

        # Create the epistasis analyzer
        self.epiAnalyzer = EpistasisAnalyzer(network, netUtils,
            seqToEscrDict, delta, bitManip)

        # Get a reference to the BitSeqManipulator in use
        self.bitManip = self.netUtils.bitManip

    # ----------------------------------------------------------------
    # Peak analysis methods
    # ----------------------------------------------------------------

    def getPeaks(self, recompute) :
        return self.peakAnalyzer.getPeaks(recompute)

    # ----------------------------------------------------------------
    # Path analysis methods
    # ----------------------------------------------------------------

    def getAccessiblePaths(self, pathLength) :
        return self.pathAnalyzer.getAccessiblePaths(pathLength)

    # ----------------------------------------------------------------
    # Epistasis analysis methods
    # ----------------------------------------------------------------

    def getEpistasis(self) :
        return self.epiAnalyzer.getEpiAll()

    # ----------------------------------------------------------------
    # Calculate mutational distances from summit for all vertices
    # ----------------------------------------------------------------

    def populateDistsToSummit(self) :
        # Convenient handle for bitManip
        bm = self.bitManip

        # Get the summit sequence
        summit = Utils.getSeqWithMaxScore(self.network,
            self.bitManip.seqLength)

        # Get vertex that represents summit
        trgtVrtx = self.netUtils.getVertex(summit, self.network)

        # Reference to the list of sequences in the network
        vertices = [ self.netUtils.getVertex(seq, self.network) \
                     for seq in self.network.vs["sequences"] ]

        self.network.vs["Distance from Summit"] = \
            [ 	len(self.network.get_shortest_paths(srcVrtx, to=trgtVrtx, \
                        weights=None, mode=igraph.OUT, output="epath")[0]) \
                for srcVrtx in vertices ]
