###############################################################################
##
## Copyright (C) 2006-2011, University of Utah. 
## All rights reserved.
## Contact: contact@vistrails.org
##
## This file is part of VisTrails.
##
## "Redistribution and use in source and binary forms, with or without 
## modification, are permitted provided that the following conditions are met:
##
##  - Redistributions of source code must retain the above copyright notice, 
##    this list of conditions and the following disclaimer.
##  - Redistributions in binary form must reproduce the above copyright 
##    notice, this list of conditions and the following disclaimer in the 
##    documentation and/or other materials provided with the distribution.
##  - Neither the name of the University of Utah nor the names of its 
##    contributors may be used to endorse or promote products derived from 
##    this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
##
###############################################################################
""" This file describe the virtual cell layout widget used in
Parameter Exploration Tab """

from PyQt4 import QtCore, QtGui
from core.inspector import PipelineInspector
from core.modules.module_registry import get_module_registry
from core.vistrail.action import Action
from core.vistrail.module_function import ModuleFunction
from core.vistrail.module_param import ModuleParam
from core.vistrail.port import Port
from core.vistrail import module
from core.vistrail import connection
import db.services.action
# FIXME broke this as Actions have been changed around
#
# from core.vistrail.action import AddModuleAction, AddConnectionAction, \
#      DeleteConnectionAction, ChangeParameterAction
from gui.common_widgets import QToolWindowInterface
from gui.paramexplore.pe_pipeline import QAnnotatedPipelineView
from gui.theme import CurrentTheme
import copy
import string

################################################################################

def decodeConfiguration(pipeline, cells):
    """ decodeConfiguration(pipeline: Pipeline,
        cells: configuration) -> decoded cells
    Convert cells of type [{(type,id): (row, column)}) to
    (mId, row, col) in a particular pipeline

    """
    decodedCells = []
    inspector = PipelineInspector()
    inspector.inspect_spreadsheet_cells(pipeline)
    inspector.inspect_ambiguous_modules(pipeline)
    orig_pipeline = pipeline

    for id_list in inspector.spreadsheet_cells:
        pipeline = orig_pipeline
        id_iter = iter(id_list)
        m = pipeline.modules[id_iter.next()]
        m_id = m.id
        for m_id in id_iter:
            pipeline = m.pipeline
            m = pipeline.modules[m_id]
        name = m.name

        if len(id_list) == 1 and m_id in inspector.annotated_modules:
            idx = inspector.annotated_modules[m_id]
        elif tuple(id_list) in inspector.annotated_modules:
            idx = inspector.annotated_modules[tuple(id_list)]
        else:
            idx = -1
        (vRow, vCol) = cells[(name, idx)]
        if len(id_list) == 1:
            decodedCells.append((m_id, vRow, vCol))
        else:
            decodedCells.append((tuple(id_list), vRow, vCol))
    return decodedCells

def _positionPipelines(sheetPrefix, sheetCount, rowCount, colCount,
                       pipelines, config, originalPipeline, controller):
    """ _positionPipelines(sheetPrefix: str, sheetCount: int, rowCount: int,
                           colCount: int, pipelines: list of Pipeline)
                           -> list of Pipelines
    Apply the virtual cell location to a list of pipelines in a
    parameter exploration given that pipelines has multiple chunk
    of sheetCount x rowCount x colCount cells

    """

    # at this point, we know that we have the spreadsheet loaded
    from packages.spreadsheet.spreadsheet_execute import \
        assignPipelineCellLocations

    registry = get_module_registry()
    (vRCount, vCCount, cells) = config
    modifiedPipelines = []
    for pId in xrange(len(pipelines)):
        root_pipeline = copy.copy(pipelines[pId])
        col = pId % colCount
        row = (pId / colCount) % rowCount
        sheet = (pId / (colCount*rowCount)) % sheetCount

        decodedCells = decodeConfiguration(root_pipeline, cells)
        # still need to go through each separately
        for (id_list, vRow, vCol) in decodedCells:
            sheet_name = "%s %d" % (sheetPrefix, sheet)
            min_row_count = rowCount * vRCount
            min_col_count = colCount * vCCount
            real_row = row*vRCount+vRow+1
            real_col = col*vCCount+vCol+1
            root_pipeline = \
                assignPipelineCellLocations(root_pipeline, sheet_name,
                                            real_row, real_col,
                                            [id_list], min_row_count,
                                            min_col_count)

        modifiedPipelines.append(root_pipeline)
    return modifiedPipelines


class QVirtualCellWindow(QtGui.QFrame, QToolWindowInterface):
    """
    QVirtualCellWindow contains a caption, a virtual cell
    configuration
    
    """
    def __init__(self, parent=None):
        """ QVirtualCellWindow(parent: QWidget) -> QVirtualCellWindow
        Initialize the widget

        """
        QtGui.QFrame.__init__(self, parent)
        self.setFrameShape(QtGui.QFrame.StyledPanel)
        self.setWindowTitle('Spreadsheet Virtual Cell')
        vLayout = QtGui.QVBoxLayout(self)
        vLayout.setMargin(2)
        vLayout.setSpacing(0)
        self.setLayout(vLayout)
        
        label = QtGui.QLabel('Arrange the cell(s) below to construct'
                             ' a virtual cell')
        font = QtGui.QFont(label.font())
        label.setFont(font)
        label.setWordWrap(True)        
        vLayout.addWidget(label)

        hLayout = QtGui.QVBoxLayout()
        hLayout.setMargin(0)
        hLayout.setSpacing(0)
        vLayout.addLayout(hLayout)
        self.config = QVirtualCellConfiguration()
        self.config.setSizePolicy(QtGui.QSizePolicy.Maximum,
                                  QtGui.QSizePolicy.Maximum)