#!/usr/bin/env python3
#
# Author: Rajendra Kumar
#
# This file is part of gcMapExplorer
# Copyright (C) 2016-2017  Rajendra Kumar, Ludvig Lizana, Per Stenberg
#
# gcMapExplorer is a free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# gcMapExplorer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gcMapExplorer.  If not, see <http://www.gnu.org/licenses/>.
#
#=============================================================================

import os
import numpy as np
import h5py

import tempfile

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.uic import loadUiType

import matplotlib as mpl
from matplotlib.ticker import AutoMinorLocator, MaxNLocator

from gcMapExplorer import cmstats
from gcMapExplorer import ccmap as cmp
from gcMapExplorer import ccmapHelpers as cmh
from . import guiHelpers

# Determine absolute path to UIs directory. Relative path from this directory does not work.
DirToThisScript = os.path.dirname(os.path.abspath(__file__))
PathToUIs = os.path.join(DirToThisScript, 'UIs')

# Dialog box to change page size by custom length
pathToThisUI = os.path.join(PathToUIs, 'dialogCustomPageSize.ui')
Ui_DialogCustomPlotsize, DialogCustomPlotsizeBase = loadUiType(pathToThisUI)
class DialogCustomPlotsize(DialogCustomPlotsizeBase, Ui_DialogCustomPlotsize):
    def __init__(self, figsize):
        super(DialogCustomPlotsize, self).__init__()
        self.setupUi(self)

        # Validate input as double
        self.lineEditHeight.setValidator(QDoubleValidator())
        self.lineEditWidth.setValidator(QDoubleValidator())

        # Store figsize for later use
        self.figsize = list(figsize)

        # Display figsize in boxes
        self.lineEditWidth.setText(str(figsize[0]))
        self.lineEditHeight.setText(str(figsize[1]))

        # GEt orientation from figure size
        self.PageOrientation = self.check_orientation()

        # Connect to return button
        self.lineEditWidth.editingFinished.connect(self.change_figsize)
        self.lineEditHeight.editingFinished.connect(self.change_figsize)
        self.buttonArrow.clicked.connect(self.change_orientation)

    def change_figsize(self):
        self.figsize = (float(self.lineEditWidth.text()), float(self.lineEditHeight.text()))
        self.PageOrientation = self.check_orientation()

    def check_orientation(self):
        self.PageOrientation = None
        if self.figsize[1] >= self.figsize[0]:
            self.lineEditOrientation.setText('Portrait')
            self.PageOrientation = 'Portrait'
        else:
            self.lineEditOrientation.setText('Landscape')
            self.PageOrientation = 'Landscape'

    def change_orientation(self):
        self.figsize = self.figsize[::-1]
        self.PageOrientation = self.check_orientation()
        # Display figsize in boxes
        self.lineEditWidth.setText(str(self.figsize[0]))
        self.lineEditHeight.setText(str(self.figsize[1]))


# Dialog box to choose and load genomic data
pathToThisUI = os.path.join(PathToUIs, 'gcmapSelectorForBrowser.ui')
Ui_gcmapSelectorDialog, gcmapSelectorDialogBase = loadUiType(pathToThisUI)
class GCMapSelectorDialog(gcmapSelectorDialogBase, Ui_gcmapSelectorDialog):
    def __init__(self, filename, hdf5=None):
        super(GCMapSelectorDialog, self).__init__()
        self.setupUi(self)

        self.filename = filename    # Input gcmap file
        self.mapName = None         # Result
        self.resolution = None      # Result
        self.dictBinSizes = None    # Dictionary of binsizes available for maps

        # h5py File object
        self.hdf5 = hdf5
        if hdf5 is None:
            self.needToCloseHdf5 = True
        else:
            self.needToCloseHdf5 = False

        self.mapList = None                              # List of maps in hdf5 file
        self.dictMapListWidgetItems = None               # Dictionary for map listWidgetItem for respective map
        self.dictResolutionListWidgetItems = None        # Dictionary for resolution listWidgetItem for selected map listWidgetItem

        self.fileNameLineEdit.setText( self.filename )   # Set name of filename
        self.getMapList()                                # Generate list of maps for first time
        self.cancelButton.setFocus()                     # Set focus on cancel button as no map is selected yet

        # Set icon for browse file
        self.browseFileButton.setIcon( self.style().standardIcon(QStyle.SP_DirOpenIcon) )

        # Connnecting widget to function
        self.fileNameLineEdit.editingFinished.connect( self.checkInputFile )

        self.mapListWidget.itemClicked.connect( self.displayResolutionList )
        self.resolutionListWidget.itemClicked.connect( self.displayAttributes )
        self.resolutionListWidget.itemClicked.connect( self.okButton.setFocus )

        self.browseFileButton.clicked.connect( self.browseFile )
        self.okButton.clicked.connect( lambda: self.onButtonClicked(self.okButton) )
        self.cancelButton.clicked.connect( lambda: self.onButtonClicked(self.cancelButton) )

        # Disable editing of table's cell
        self.mapAttrsTableWidget.setEditTriggers( QAbstractItemView.NoEditTriggers )

    def getMapList(self):
        """Read gcmap file, make a list of maps and display it in QListWidget
        """
        if self.hdf5 is None:
            self.hdf5 = h5py.File(self.filename)

        self.mapList = cmh.sorted_nicely( list( self.hdf5.keys() ) )

        self.dictMapListWidgetItems = dict()
        for key in self.mapList:
            listItem = QListWidgetItem(key, self.mapListWidget)
            self.dictMapListWidgetItems[key] = listItem

    def displayResolutionList(self, item):
        """ Generate a resolution list for selected map
        """

        mapName = self.getMapForListWidget(item)

		# determining finest resolution map
        if self.dictBinSizes is None:
            self.dictBinSizes = dict()

        if mapName not in self.dictBinSizes:
            binsizes = []
            for key in self.hdf5[mapName]:
                if 'bNoData' not in key:
                    binsizes.append( self.hdf5[mapName][key].attrs['binsize'] )
            binsizes = sorted(binsizes)
            self.dictBinSizes[mapName] = binsizes

        if self.dictResolutionListWidgetItems is not None:
            for i in range(self.resolutionListWidget.count()):
                item = self.resolutionListWidget.takeItem( 0 )
                del item

        self.dictResolutionListWidgetItems = None
        self.dictResolutionListWidgetItems = dict()
        for binsize in self.dictBinSizes[mapName]:
            listItem = QListWidgetItem(cmp.binsizeToResolution(binsize), self.resolutionListWidget)
            self.dictResolutionListWidgetItems[binsize] = listItem

        resolutionItem = self.dictResolutionListWidgetItems[ self.dictBinSizes[mapName][0] ]
        self.resolutionListWidget.setCurrentItem( resolutionItem )
        self.displayAttributes( resolutionItem )


    def displayAttributes(self, item):
        """When a Map is selected, display its attributes in table (QTableWidget)
        """
        mapName = self.getMapForListWidget( self.mapListWidget.currentItem() )
        resolution = self.getResolutionForListWidget( item )

        self.mapAttrsTableWidget.item(0, 0).setText( str(self.hdf5[mapName].attrs['xlabel']) )
        self.mapAttrsTableWidget.item(1, 0).setText( str(self.hdf5[mapName].attrs['ylabel']) )

        attrs = ['minvalue', 'maxvalue', 'binsize', 'xshape', 'yshape']
        for i in range(len(attrs)):
            self.mapAttrsTableWidget.item(i+2, 0).setText( str(self.hdf5[mapName][resolution].attrs[attrs[i]]) )

    def getMapForListWidget(self, item):
        """Get map name for given QListWidgetItem
        """
        mapName = None
        for key in self.mapList:
            if item is self.dictMapListWidgetItems[key]:
                mapName = key
                break
        return mapName

    def getResolutionForListWidget(self, item):
        """Get map name for given QListWidgetItem
        """

        mapName = self.getMapForListWidget( self.mapListWidget.currentItem() )
        resolution = None

        for binsize in self.dictBinSizes[mapName]:
            if item is self.dictResolutionListWidgetItems[binsize]:
                resolution = cmp.binsizeToResolution(binsize)
                break
        return resolution

    def resetForNewFile(self):
        """Reset all widgets and class attributes.
        Call it when a new valid file is selected.
        """
        for i in range(self.mapListWidget.count()):
            item = self.mapListWidget.takeItem( 0 )
            del item

        self.mapList = None
        self.dictMapListWidgetItems = None

        for i in range(7):
            self.mapAttrsTableWidget.item(i, 0).setText('Select a Map')

        if self.needToCloseHdf5:
            self.hdf5.close()
        self.hdf5 = None
        self.cancelButton.setFocus()

    def checkInputFile(self):
        """Check input file exist. If file exist, read it, generate a list of map, and show it.
        """
        inputFile = str( self.fileNameLineEdit.text() )
        if inputFile and not os.path.isfile(inputFile):
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'File not found.', QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()

            self.fileNameLineEdit.clear()
            self.fileNameLineEdit.setText(self.filename)
        else:
            self.filename = inputFile
            self.resetForNewFile()
            self.getMapList()

    def browseFile(self):
        """Browse and select input text file. If file is selected, read it, generate a list of map, and show it.
        """
        # A dialog box will be displayed to select a text file and path will be stored in the cell
        file_choices = "gcmap file (*.gcmap);;All files (*.*)"
        path = QFileDialog.getOpenFileName(self, 'Select a gcmap file', '', file_choices)
        if path[0]:
            self.fileNameLineEdit.setText( path[0] )
            self.resetForNewFile()
            self.getMapList()

    def onButtonClicked(self, button):
        """when ok/cancel button is clicked
        """
        if button is self.okButton:
            item = self.mapListWidget.currentItem()
            if item:
                self.mapName = self.getMapForListWidget(item)

                resItem = self.resolutionListWidget.currentItem()
                if resItem:
                    self.resolution = self.getResolutionForListWidget( resItem )
                else:
                    self.reject()

                self.accept()
            else:
                self.reject()
        else:
            self.reject()


# Dialog box to change axis properties
pathToThisUI = os.path.join(PathToUIs, 'dialogAxisProps.ui')
Ui_DialogAxisProps, QDialogAxisPropsBase = loadUiType(pathToThisUI)
class DialogAxisProps(QDialogAxisPropsBase, Ui_DialogAxisProps):
    def __init__(self, canvas, tabIdx, axes, axesProps=None, xTickLocations=None, xTickLabelTexts=None, yTickLocations=None, yTickLabelTexts=None):
        super(DialogAxisProps, self).__init__()
        self.setupUi(self)

        self.tabWidgetAxisProps.setCurrentIndex(tabIdx)
        self.axes = axes
        self.canvas = canvas

        self.init_font_matplotlib_qt()

        if axesProps is None:
            self.axesProps = AxesProperties(axes, xTickLocations, xTickLabelTexts, yTickLocations, yTickLabelTexts)
        else:
            self.axesProps = axesProps

        # Display X label properties
        self.displayXLabelPropsOnTabWidget()

        # Display Y label properties
        self.displayYLabelPropsOnTabWidget()

        # Display X tick label properties
        self.displayXTickLabelPropsOnTabWidget()

        # Display X tick label properties
        self.displayYTickLabelPropsOnTabWidget()

        # What happens when buttons are clicked
        self.xTickShowMinorTicksCBox.currentIndexChanged.connect(self.xMinorTicksController)
        self.yTickShowMinorTicksCBox.currentIndexChanged.connect(self.yMinorTicksController)
        self.okCancelApplyButtonBox.clicked.connect(self.uponButtonClicked)

    def update_axes(self, axes, axesProps, xTickLocations=None, xTickLabelTexts=None, yTickLocations=None, yTickLabelTexts=None):
        ''' If dialog box is already opened by user, use this function to update dialog box for given axes and axes properties
        '''
        self.axes = axes
        self.axesProps = axesProps

        # Display X label properties
        self.displayXLabelPropsOnTabWidget()

        # Display Y label properties
        self.displayYLabelPropsOnTabWidget()

        # Display X tick label properties
        self.displayXTickLabelPropsOnTabWidget()

        # Display X tick label properties
        self.displayYTickLabelPropsOnTabWidget()

    def init_font_matplotlib_qt(self):
        ''' Initialize font name list QFontComboBox.
        Also adds font from matplotlib default fonts
        '''
        # Font database of qt
        self.qtFontDatabase = QFontDatabase()

        # Getting path of matplotlib ttf directory
        mplDataPath = mpl.rcParams['datapath']
        mplFontPath = os.path.join(mplDataPath, 'fonts')
        mplTtfFontPath = os.path.join(mplFontPath, 'ttf')

        # Buinding ttf files list
        mplTtfList = []
        for f in os.listdir(mplTtfFontPath):
            if f.endswith('.ttf'):
                mplTtfList.append(os.path.join(mplTtfFontPath, f))

        # Getting name of each font from ttf files
        mplFontNameList = [mpl.font_manager.FontProperties(fname=fname).get_name() for fname in mplTtfList]

        # Getting name of each font from qt font database
        qtFontNameListQtype = self.qtFontDatabase.families()
        qtFontNameList =  [ str(qtFont) for qtFont in qtFontNameListQtype ]

        # Comapring and adding matplotlib font to qt font database
        for i in range(len(mplFontNameList)):
            matched = False
            for qtFont in qtFontNameList:
                if str(qtFont) == mplFontNameList[i]:
                    matched = True

            if not matched:
                self.qtFontDatabase.addApplicationFont(mplTtfList[i])

    def is_font_exist_in_mpl(self, fontname):
        result = None
        result = mpl.font_manager.findfont(mpl.font_manager.FontProperties(family=fontname))

        if mpl.font_manager.FontProperties(fname=result).get_name() == fontname:
            return True
        else:
            return False

    def displayXLabelPropsOnTabWidget(self):
        ''' Display X Label properties on Tab Widget
        '''
        # Setting X label in tab widget
        self.xLabelTitleLineEdit.setText(self.axesProps.xLabel['Text'])

        # Setting x label postion in Show Label combo box
        if self.axesProps.xLabel['Show Label'] == 'bottom':
            self.xLabelShowLabelCBox.setCurrentIndex(0)
        if self.axesProps.xLabel['Show Label'] == 'top':
            self.xLabelShowLabelCBox.setCurrentIndex(1)
        if self.axesProps.xLabel['Show Label'] == 'none':
            self.xLabelShowLabelCBox.setCurrentIndex(2)

        # Setting font in qfontcombobox
        qfont = self.qtFontDatabase.font(self.axesProps.xLabel['Font Name'], 'normal', self.axesProps.xLabel['Font Size'])
        self.xLabelFontNameCBox.setCurrentFont(qfont)

        # setting font size in tab widget
        self.xLabelFontSizeCBox.setValidator(QIntValidator())
        self.xLabelFontSizeCBox.setCurrentText(str(self.axesProps.xLabel['Font Size']))

        # padding
        self.xLabelPaddingSpinbox.setValue(self.axesProps.xLabel['padding'])

    def changeXLabelPropsOnAxes(self):
        ''' Changes X Label properties on axes plot
        '''
        # Check whether x-label is changed in tab-widget and then change it in plot
        if self.axesProps.xLabel['Text'] != self.xLabelTitleLineEdit.text():
            self.axes.get_xaxis().set_label_text(str(self.xLabelTitleLineEdit.text()))

        # Check whether font size is changed and then change it in plot
        if self.axesProps.xLabel['Font Size'] != int( self.xLabelFontSizeCBox.currentText() ):
            self.axes.get_xaxis().get_label().set_fontsize( int( self.xLabelFontSizeCBox.currentText() ) )

        # Check whether font name is changed in tab-widget and then chenge it in plot
        qfont = self.xLabelFontNameCBox.currentFont()
        if self.is_font_exist_in_mpl(str(qfont.family())):
            if self.axesProps.xLabel['Font Name'] != str(qfont.family()):
                self.axes.get_xaxis().get_label().set_fontname(str(qfont.family()))
        else:
            # resetting font in qfontcombobox if font is not present in matplotlib
            qfont = self.qtFontDatabase.font(self.axesProps.xLabel['Font Name'], 'normal', self.axesProps.xLabel['Font Size'])
            self.xLabelFontNameCBox.setCurrentFont(qfont)
            self.axes.get_xaxis().get_label().set_fontname(str(qfont.family()))

        # Check whether x-lable position is changed in widget and then change it
        if self.xLabelShowLabelCBox.currentIndex() == 0:
            self.axes.get_xaxis().get_label().set_visible(True)
            self.axes.get_xaxis().set_label_position('bottom')
        if self.xLabelShowLabelCBox.currentIndex() == 1:
            self.axes.get_xaxis().get_label().set_visible(True)
            self.axes.get_xaxis().set_label_position('top')
        if self.xLabelShowLabelCBox.currentIndex() == 2:
            self.axes.get_xaxis().get_label().set_visible(False)

        # Padding
        self.axes.xaxis.labelpad = self.xLabelPaddingSpinbox.value()

    def displayYLabelPropsOnTabWidget(self):
        ''' Display Y Label properties on Tab Widget
        '''
        # Setting Y label in tab widget
        self.yLabelTitleLineEdit.setText(self.axesProps.yLabel['Text'])

        # Setting Y label postion in Show Label combo box
        if self.axesProps.yLabel['Show Label'] == 'left':
            self.yLabelShowLabelCBox.setCurrentIndex(0)
        if self.axesProps.yLabel['Show Label'] == 'right':
            self.yLabelShowLabelCBox.setCurrentIndex(1)
        if self.axesProps.yLabel['Show Label'] == 'none':
            self.yLabelShowLabelCBox.setCurrentIndex(2)

        # Setting font in qfontcombobox
        qfont = self.qtFontDatabase.font(self.axesProps.yLabel['Font Name'], 'normal', self.axesProps.yLabel['Font Size'])
        self.yLabelFontNameCBox.setCurrentFont(qfont)

        # setting font size in tab widget
        self.yLabelFontSizeCBox.setValidator(QIntValidator())
        self.yLabelFontSizeCBox.setCurrentText(str(self.axesProps.yLabel['Font Size']))

        # padding
        self.yLabelPaddingSpinbox.setValue(self.axesProps.yLabel['padding'])

    def changeYLabelPropsOnAxes(self):
        ''' Changes Y Label properties on axes plot
        '''
        # Check whether x-label is changed in tab-widget and then change it in plot
        if self.axesProps.yLabel['Text'] != self.yLabelTitleLineEdit.text():
            self.axes.get_yaxis().set_label_text(str(self.yLabelTitleLineEdit.text()))

        # Check whether font size is changed and then change it in plot
        if self.axesProps.yLabel['Font Size'] != int( self.yLabelFontSizeCBox.currentText() ):
            self.axes.get_yaxis().get_label().set_fontsize( int( self.yLabelFontSizeCBox.currentText() ) )

        # Check whether font name is changed in tab-widget and then chenge it in plot
        qfont = self.yLabelFontNameCBox.currentFont()
        if self.is_font_exist_in_mpl(str(qfont.family())):
            if self.axesProps.yLabel['Font Name'] != str(qfont.family()):
                self.axes.get_yaxis().get_label().set_fontname(str(qfont.family()))
        else:
            # Setting font in qfontcombobox if font is not present in matplotlib
            qfont = self.qtFontDatabase.font(self.axesProps.yLabel['Font Name'], 'normal', self.axesProps.yLabel['Font Size'])
            self.yLabelFontNameCBox.setCurrentFont(qfont)
            self.axes.get_yaxis().get_label().set_fontname(str(qfont.family()))

        # Check whether y-lable position is changed in widget and then change it
        if self.yLabelShowLabelCBox.currentIndex() == 0:
            self.axes.get_yaxis().get_label().set_visible(True)
            self.axes.get_yaxis().set_label_position('left')
        if self.yLabelShowLabelCBox.currentIndex() == 1:
            self.axes.get_yaxis().get_label().set_visible(True)
            self.axes.get_yaxis().set_label_position('right')
        if self.yLabelShowLabelCBox.currentIndex() == 2:
            self.axes.get_yaxis().get_label().set_visible(False)

        # Padding
        self.axes.yaxis.labelpad = self.yLabelPaddingSpinbox.value()

    def displayXTickLabelPropsOnTabWidget(self):
        # Display tick label position
        if self.axesProps.xTickLabel['Label Position'] == 'bottom':
            self.xTickShowTickLabelsCBox.setCurrentIndex(0)
        if self.axesProps.xTickLabel['Label Position'] == 'top':
            self.xTickShowTickLabelsCBox.setCurrentIndex(1)
        if self.axesProps.xTickLabel['Label Position'] == 'both':
            self.xTickShowTickLabelsCBox.setCurrentIndex(2)
        if self.axesProps.xTickLabel['Label Position'] == 'none':
            self.xTickShowTickLabelsCBox.setCurrentIndex(3)

        # Display label rotation
        self.xTickLabelRotationCBox.setValidator(QIntValidator())
        self.xTickLabelRotationCBox.setCurrentText(str(self.axesProps.xTickLabel['Label Rotation']))

        # Setting font in qfontcombobox
        qfont = self.qtFontDatabase.font(self.axesProps.xTickLabel['Font Name'], 'normal', self.axesProps.xTickLabel['Font Size'])
        self.xTickFontNameCBox.setCurrentFont(qfont)

        # setting font size in tab widget
        self.xTickFontSizeCBox.setValidator(QIntValidator())
        self.xTickFontSizeCBox.setCurrentText(str(self.axesProps.xTickLabel['Font Size']))

        # padding
        self.xTickLabelPaddingSpinbox.setValue(self.axesProps.xTickLabel['padding'])

        # number of ticks
        self.xTickIntervalsLineEdit.setValidator(QIntValidator())
        self.xTickIntervalsLineEdit.setText(str(self.axesProps.xTickLabel['Tick Intervals']))

        # Ticks position: top, bottom, both, none
        if self.axesProps.xTickLabel['Tick Position'] == 'both':
            self.xTickShowTicksCBox.setCurrentIndex(0)
        if self.axesProps.xTickLabel['Tick Position'] == 'bottom':
            self.xTickShowTicksCBox.setCurrentIndex(1)
        if self.axesProps.xTickLabel['Tick Position'] == 'top':
            self.xTickShowTicksCBox.setCurrentIndex(2)
        if self.axesProps.xTickLabel['Tick Position'] == 'none':
            self.xTickShowTicksCBox.setCurrentIndex(3)

        # Major tick length
        self.xTickMajorTickLenLineEdit.setValidator(QDoubleValidator())
        self.xTickMajorTickLenLineEdit.setText(str(self.axesProps.xTickLabel['Major Ticks Length']))

        # Major tick width
        self.xTickMajorTickWidthLineEdit.setValidator(QDoubleValidator())
        self.xTickMajorTickWidthLineEdit.setText(str(self.axesProps.xTickLabel['Major Ticks Width']))

        # Show minor ticks
        if self.axesProps.xTickLabel['Minor Ticks Visible']:
            self.xTickShowMinorTicksCBox.setCurrentIndex(1)
        else:
            num_minorticks = len(self.axes.get_xaxis().get_minor_ticks()) / ( len(self.axes.get_xaxis().get_major_ticks()) - 1)
            self.xTickShowMinorTicksCBox.setCurrentIndex( num_minorticks )

        # Minor ticks height
        self.xTickMinorTickLenLineEdit.setValidator(QDoubleValidator())
        if self.axesProps.xTickLabel['Minor Ticks Length'] is not None:
            self.xTickMinorTickLenLineEdit.setText(str(self.axesProps.xTickLabel['Minor Ticks Length']))

        # Minor ticks width
        self.xTickMinorTickWidthLineEdit.setValidator(QDoubleValidator())
        if self.axesProps.xTickLabel['Minor Ticks Width'] is not None:
            self.xTickMinorTickWidthLineEdit.setText(str(self.axesProps.xTickLabel['Minor Ticks Width']))

    def changeXTickLabelPropsOnAxes(self):
        # Change tick label  and ticks position
        ticks = self.axes.get_xaxis().get_major_ticks()

        # Bottom tick label
        if self.xTickShowTickLabelsCBox.currentIndex() == 0:
            for tick in ticks:
                tick.label1On = True
                tick.label2On = False
        # top tick label
        if self.xTickShowTickLabelsCBox.currentIndex() == 1:
            for tick in ticks:
                tick.label1On = False
                tick.label2On = True
        # tick label at both side
        if self.xTickShowTickLabelsCBox.currentIndex() == 2:
            for tick in ticks:
                tick.label1On = True
                tick.label2On = True
        # hide tick label
        if self.xTickShowTickLabelsCBox.currentIndex() == 3:
            for tick in ticks:
                tick.label1On = False
                tick.label2On = False


        ticks = self.axes.get_xaxis().get_major_ticks()
        # Both ticks position
        if self.xTickShowTicksCBox.currentIndex() == 0:
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = True
        # bottom ticks position
        if self.xTickShowTicksCBox.currentIndex() == 1:
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = False
        # top ticks position
        if self.xTickShowTicksCBox.currentIndex() == 2:
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = True
        # hide ticks position
        if self.xTickShowTicksCBox.currentIndex() == 3:
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = False


        # Change Tick labels rotation
        labels = self.axes.get_xticklabels()
        for label in labels:
            label.set_rotation( int( self.xTickLabelRotationCBox.currentText() ) )


        # Check whether font name is changed in tab-widget and then chenge it in plot
        qfont = self.xTickFontNameCBox.currentFont()
        if self.is_font_exist_in_mpl(str(qfont.family())):
            for label in labels:
                label.set_fontname( str(qfont.family()) )
        else:
            # Setting font in qfontcombobox if font is not present in matplotlib
            qfont = self.qtFontDatabase.font(self.axesProps.xTickLabel['Font Name'], 'normal', self.axesProps.xTickLabel['Font Size'])
            self.xTickFontNameCBox.setCurrentFont(qfont)
            for label in labels:
                label.set_fontname( str(qfont.family()) )

        # font size of labels
        for label in labels:
            label.set_fontsize( int(self.xTickFontSizeCBox.currentText()) )

        #Setting tick-label padding
        self.axes.xaxis.set_tick_params(pad=self.xTickLabelPaddingSpinbox.value())

        #TODO number of ticks
        num_tick_intervals = int ( self.xTickIntervalsLineEdit.text() )
        if num_tick_intervals != self.axesProps.xTickLabel['Tick Intervals']:
            self.axesProps.modify_xtick_intervals(num_tick_intervals)
            self.xTickIntervalsLineEdit.setText( str(len(self.axes.get_xaxis().get_major_ticks())) )
            self.axesProps.xTickLabel['Tick Intervals'] = len(self.axes.get_xaxis().get_major_ticks())

        # Major tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_xaxis().get_majorticklines()
        if ticklines:
            for tickline in ticklines:
                tickline.set_markersize( float( self.xTickMajorTickLenLineEdit.text()) )
                tickline.set_markeredgewidth( float( self.xTickMajorTickWidthLineEdit.text()) )


        # If minor ticks are enabled, show them and reset their postions according to major ticks
        if self.xTickShowMinorTicksCBox.currentIndex() != 0:

            # Setting minor locator
            minorLocator = AutoMinorLocator( self.xTickShowMinorTicksCBox.currentIndex() + 1 )
            self.axes.get_xaxis().set_minor_locator(minorLocator)

            if not str(self.xTickMinorTickLenLineEdit.text()) and not str(self.xTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='x', which='minor', bottom=True, top=True)
            if str(self.xTickMinorTickLenLineEdit.text()) and not str(self.xTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='x', which='minor', length = float( self.xTickMinorTickLenLineEdit.text() ) )
            if not str(self.xTickMinorTickLenLineEdit.text()) and str(self.xTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='x', which='minor', width =  float( self.xTickMinorTickWidthLineEdit.text() ) )
            if str(self.xTickMinorTickLenLineEdit.text()) and str(self.xTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='x', which='minor', length = float( self.xTickMinorTickLenLineEdit.text()), width =  float( self.xTickMinorTickWidthLineEdit.text()),  bottom=True, top=True)


            # Update length and width of minor tick lines in widget
            ticklines = self.axes.get_xaxis().get_minorticklines()
            self.axesProps.xTickLabel['Minor Ticks Length'] = ticklines[0].get_markersize()
            self.axesProps.xTickLabel['Minor Ticks Width'] = ticklines[0].get_markeredgewidth()
            self.xTickMinorTickLenLineEdit.setText(str(self.axesProps.xTickLabel['Minor Ticks Length']))
            self.xTickMinorTickWidthLineEdit.setText(str(self.axesProps.xTickLabel['Minor Ticks Width']))

            # Reset positions of minor ticks according to major ticks
            ticks = self.axes.get_xaxis().get_minor_ticks()
            # Bottom tick label
            if self.xTickShowTicksCBox.currentIndex() == 0:
                for tick in ticks:
                    tick.tick1On = True
                    tick.tick2On = True
            # top tick label
            if self.xTickShowTicksCBox.currentIndex() == 1:
                for tick in ticks:
                    tick.tick1On = True
                    tick.tick2On = False
            # tick label at both side
            if self.xTickShowTicksCBox.currentIndex() == 2:
                for tick in ticks:
                    tick.tick1On = False
                    tick.tick2On = True
            # hide tick label
            if self.xTickShowTicksCBox.currentIndex() == 3:
                for tick in ticks:
                    tick.tick1On = False
                    tick.tick2On = False

        # If minor ticks are disabled, remove them
        if self.xTickShowMinorTicksCBox.currentIndex() == 0:
            ticks = self.axes.get_xaxis().get_minor_ticks()
            if ticks:
                for tick in ticks:
                    tick.tick1On = False
                    tick.tick2On = False

    def displayYTickLabelPropsOnTabWidget(self):
        # Display tick label positionx
        if self.axesProps.yTickLabel['Label Position'] == 'left':
            self.yTickShowTickLabelsCBox.setCurrentIndex(0)
        if self.axesProps.yTickLabel['Label Position'] == 'right':
            self.yTickShowTickLabelsCBox.setCurrentIndex(1)
        if self.axesProps.yTickLabel['Label Position'] == 'both':
            self.yTickShowTickLabelsCBox.setCurrentIndex(2)
        if self.axesProps.yTickLabel['Label Position'] == 'none':
            self.yTickShowTickLabelsCBox.setCurrentIndex(3)

        # Display label rotation
        self.yTickLabelRotationCBox.setValidator(QIntValidator())
        self.yTickLabelRotationCBox.setCurrentText(str(self.axesProps.yTickLabel['Label Rotation']))

        # Setting font in qfontcombobox
        qfont = self.qtFontDatabase.font(self.axesProps.yTickLabel['Font Name'], 'normal', self.axesProps.yTickLabel['Font Size'])
        self.yTickFontNameCBox.setCurrentFont(qfont)

        # setting font size in tab widget
        self.yTickFontSizeCBox.setValidator(QIntValidator())
        self.yTickFontSizeCBox.setCurrentText(str(self.axesProps.yTickLabel['Font Size']))

        # padding
        self.yTickLabelPaddingSpinbox.setValue(self.axesProps.yTickLabel['padding'])

        # number of ticks
        self.yTickIntervalsLineEdit.setValidator(QIntValidator())
        self.yTickIntervalsLineEdit.setText(str(self.axesProps.yTickLabel['Tick Intervals']))

        # Ticks position: top, bottom, both, none
        if self.axesProps.yTickLabel['Tick Position'] == 'both':
            self.yTickShowTicksCBox.setCurrentIndex(0)
        if self.axesProps.yTickLabel['Tick Position'] == 'left':
            self.yTickShowTicksCBox.setCurrentIndex(1)
        if self.axesProps.yTickLabel['Tick Position'] == 'right':
            self.yTickShowTicksCBox.setCurrentIndex(2)
        if self.axesProps.yTickLabel['Tick Position'] == 'none':
            self.yTickShowTicksCBox.setCurrentIndex(3)

        # Major tick length
        self.yTickMajorTickLenLineEdit.setValidator(QDoubleValidator())
        self.yTickMajorTickLenLineEdit.setText(str(self.axesProps.yTickLabel['Major Ticks Length']))

        # Major tick width
        self.yTickMajorTickWidthLineEdit.setValidator(QDoubleValidator())
        self.yTickMajorTickWidthLineEdit.setText(str(self.axesProps.yTickLabel['Major Ticks Width']))

        # Show minor ticks
        if self.axesProps.yTickLabel['Minor Ticks Visible']:
            self.yTickShowMinorTicksCBox.setCurrentIndex(1)
        else:
            num_minorticks = len(self.axes.get_yaxis().get_minor_ticks()) / ( len(self.axes.get_yaxis().get_major_ticks()) - 1)
            self.yTickShowMinorTicksCBox.setCurrentIndex( num_minorticks )

        # Minor ticks height
        self.yTickMinorTickLenLineEdit.setValidator(QDoubleValidator())
        if self.axesProps.yTickLabel['Minor Ticks Length'] is not None:
            self.yTickMinorTickLenLineEdit.setText(str(self.axesProps.yTickLabel['Minor Ticks Length']))

        # Minor ticks width
        self.yTickMinorTickWidthLineEdit.setValidator(QDoubleValidator())
        if self.axesProps.yTickLabel['Minor Ticks Width'] is not None:
            self.yTickMinorTickWidthLineEdit.setText(str(self.axesProps.yTickLabel['Minor Ticks Width']))

    def changeYTickLabelPropsOnAxes(self):
        # Change tick label  and ticks position
        ticks = self.axes.get_yaxis().get_major_ticks()

        # Bottom tick label
        if self.yTickShowTickLabelsCBox.currentIndex() == 0:
            for tick in ticks:
                tick.label1On = True
                tick.label2On = False
        # top tick label
        if self.yTickShowTickLabelsCBox.currentIndex() == 1:
            for tick in ticks:
                tick.label1On = False
                tick.label2On = True
        # tick label at both side
        if self.yTickShowTickLabelsCBox.currentIndex() == 2:
            for tick in ticks:
                tick.label1On = True
                tick.label2On = True
        # hide tick label
        if self.yTickShowTickLabelsCBox.currentIndex() == 3:
            for tick in ticks:
                tick.label1On = False
                tick.label2On = False


        ticks = self.axes.get_yaxis().get_major_ticks()
        # Both ticks position
        if self.yTickShowTicksCBox.currentIndex() == 0:
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = True
        # bottom ticks position
        if self.yTickShowTicksCBox.currentIndex() == 1:
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = False
        # top ticks position
        if self.yTickShowTicksCBox.currentIndex() == 2:
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = True
        # hide ticks position
        if self.yTickShowTicksCBox.currentIndex() == 3:
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = False


        # Change Tick labels rotation
        labels = self.axes.get_yticklabels()
        for label in labels:
            label.set_rotation( int( self.yTickLabelRotationCBox.currentText() ) )


        # Check whether font name is changed in tab-widget and then chenge it in plot
        qfont = self.yTickFontNameCBox.currentFont()
        if self.is_font_exist_in_mpl(str(qfont.family())):
            for label in labels:
                label.set_fontname( str(qfont.family()) )
        else:
            # Setting font in qfontcombobox if font is not present in matplotlib
            qfont = self.qtFontDatabase.font(self.axesProps.yTickLabel['Font Name'], 'normal', self.axesProps.yTickLabel['Font Size'])
            self.yTickFontNameCBox.setCurrentFont(qfont)
            for label in labels:
                label.set_fontname( str(qfont.family()) )

        # font size of labels
        for label in labels:
            label.set_fontsize( int(self.yTickFontSizeCBox.currentText()) )

        #Setting tick-label padding
        self.axes.yaxis.set_tick_params(pad=self.yTickLabelPaddingSpinbox.value())

        #TODO number of ticks
        num_tick_intervals = int ( self.yTickIntervalsLineEdit.text() )
        if num_tick_intervals != self.axesProps.yTickLabel['Tick Intervals']:
            self.axesProps.modify_ytick_intervals(num_tick_intervals)
            self.yTickIntervalsLineEdit.setText( str(len(self.axes.get_yaxis().get_major_ticks())) )
            self.axesProps.yTickLabel['Tick Intervals'] = len(self.axes.get_yaxis().get_major_ticks())

        # Major tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_yaxis().get_majorticklines()
        if ticklines:
            for tickline in ticklines:
                tickline.set_markersize( float( self.yTickMajorTickLenLineEdit.text()) )
                tickline.set_markeredgewidth( float( self.yTickMajorTickWidthLineEdit.text()) )


        # If minor ticks are enabled, show them and reset their postions according to major ticks
        if self.yTickShowMinorTicksCBox.currentIndex() != 0:

            # Setting minor locator
            minorLocator = AutoMinorLocator( self.yTickShowMinorTicksCBox.currentIndex() + 1 )
            self.axes.get_yaxis().set_minor_locator(minorLocator)

            if not str(self.yTickMinorTickLenLineEdit.text()) and not str(self.yTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='y', which='minor', bottom=True, top=True)
            if str(self.yTickMinorTickLenLineEdit.text()) and not str(self.yTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='y', which='minor', length = float( self.yTickMinorTickLenLineEdit.text() ) )
            if not str(self.yTickMinorTickLenLineEdit.text()) and str(self.yTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='y', which='minor', width =  float( self.yTickMinorTickWidthLineEdit.text() ) )
            if str(self.yTickMinorTickLenLineEdit.text()) and str(self.yTickMinorTickWidthLineEdit.text()):
                self.axes.tick_params(axis='y', which='minor', length = float( self.yTickMinorTickLenLineEdit.text()), width =  float( self.yTickMinorTickWidthLineEdit.text()),  bottom=True, top=True)


            # Update length and width of minor tick lines in widget
            ticklines = self.axes.get_yaxis().get_minorticklines()
            self.axesProps.yTickLabel['Minor Ticks Length'] = ticklines[0].get_markersize()
            self.axesProps.yTickLabel['Minor Ticks Width'] = ticklines[0].get_markeredgewidth()
            self.yTickMinorTickLenLineEdit.setText(str(self.axesProps.yTickLabel['Minor Ticks Length']))
            self.yTickMinorTickWidthLineEdit.setText(str(self.axesProps.yTickLabel['Minor Ticks Width']))

            # Reset positions of minor ticks according to major ticks
            ticks = self.axes.get_yaxis().get_minor_ticks()
            # Bottom tick label
            if self.yTickShowTicksCBox.currentIndex() == 0:
                for tick in ticks:
                    tick.tick1On = True
                    tick.tick2On = True
            # top tick label
            if self.yTickShowTicksCBox.currentIndex() == 1:
                for tick in ticks:
                    tick.tick1On = True
                    tick.tick2On = False
            # tick label at both side
            if self.yTickShowTicksCBox.currentIndex() == 2:
                for tick in ticks:
                    tick.tick1On = False
                    tick.tick2On = True
            # hide tick label
            if self.yTickShowTicksCBox.currentIndex() == 3:
                for tick in ticks:
                    tick.tick1On = False
                    tick.tick2On = False

        # If minor ticks are disabled, remove them
        if self.yTickShowMinorTicksCBox.currentIndex() == 0:
            ticks = self.axes.get_yaxis().get_minor_ticks()
            if ticks:
                for tick in ticks:
                    tick.tick1On = False
                    tick.tick2On = False

    def uponButtonClicked(self, button):
        if button.text() == 'Apply':
            self.changeAxisPropsOnAxes()
        if button.text() == 'Cancel':
            self.done(QDialog.Rejected)
        if button.text() == 'OK':
            self.changeAxisPropsOnAxes()
            self.done(QDialog.Accepted)

    def changeAxisPropsOnAxes(self):
        self.changeXLabelPropsOnAxes()
        self.changeYLabelPropsOnAxes()
        self.changeXTickLabelPropsOnAxes()
        self.changeYTickLabelPropsOnAxes()
        self.canvas.draw()
        self.axesProps.get_from_axes()

    def xMinorTicksController(self):
        ''' To modify minor ticks properties when user enable or disable it
        '''
        if self.xTickShowMinorTicksCBox.currentIndex() != 0:
            self.xTickMinorTickLenLineEdit.setEnabled(True)
            self.xTickMinorTickWidthLineEdit.setEnabled(True)
        if self.xTickShowMinorTicksCBox.currentIndex() == 0:
            self.xTickMinorTickLenLineEdit.setEnabled(False)
            self.xTickMinorTickWidthLineEdit.setEnabled(False)

    def yMinorTicksController(self):
        ''' To modify minor ticks properties when user enable or disable it
        '''
        if self.yTickShowMinorTicksCBox.currentIndex() != 0:
            self.yTickMinorTickLenLineEdit.setEnabled(True)
            self.yTickMinorTickWidthLineEdit.setEnabled(True)
        if self.yTickShowMinorTicksCBox.currentIndex() == 0:
            self.yTickMinorTickLenLineEdit.setEnabled(False)
            self.yTickMinorTickWidthLineEdit.setEnabled(False)



# Dialog box to select and load genomic data
pathToThisUI = os.path.join(PathToUIs, 'genomicDataSelector.ui')
Ui_DialogGenomicsDataSelector, QDialogGenomicsDataSelectorBase = loadUiType(pathToThisUI)
class DialogGenomicsDataSelector(QDialogGenomicsDataSelectorBase, Ui_DialogGenomicsDataSelector):
    def __init__(self, data, title, requestedBinsize=None):
        super(DialogGenomicsDataSelector, self).__init__()
        self.setupUi(self)
        self.data = data
        self.requestedBinsize = requestedBinsize
        self.resolutions = None
        self.dataNames = None
        self.coarse_methods_name = { 'min':'Minimum', 'max':'Maximum', 'median':'Median', 'amean':'Arithmatic Mean', 'gmean':'Geometric Mean', 'hmean':'Harmonic Mean' }
        self.coarse_methods_name_r = { 'Minimum':'min', 'Maximum':'max', 'Median':'median', 'Arithmatic Mean':'amean', 'Geometric Mean':'gmean', 'Harmonic Mean':'hmean' }
        self.selected_data = None
        self.whereToPlot = None

        # Add chromosomes in list
        self.chroms = []
        for key in self.data:
            self.chroms.append(key)
        self.chromNameListWidget.addItems(cmh.sorted_nicely(self.chroms))

        # Set title
        self.titleText.setText(title)

        # Connect to interface
        self.chromNameListWidget.itemSelectionChanged.connect(self.chromosomeSelector)
        self.chromResolutionListWidget.itemSelectionChanged.connect(self.resolutionSelector)
        self.openAbortButton.clicked.connect(self.on_button_clicked)

    def chromosomeSelector(self):
        """ To display/change resolution list when a chromosome is selected by user
        """

        # Removing resolutions list
        if self.resolutions is not None:
            for i in range(len(self.resolutions)):
                dummy = self.chromResolutionListWidget.takeItem(0)
                del dummy

            self.resolutions = None

        # Removing dataNames list
        if self.dataNames is not None:
            for i in range(len(self.dataNames)):
                dummy = self.dataNameListWidget.takeItem(0)
                del dummy

            self.dataNames = None

        # Generating new resolution list
        self.resolutions = []
        currentText = self.chromNameListWidget.currentItem().text()
        for key in self.data[currentText]:
            self.resolutions.append(key)

        # Sort from fine to coarse resolution
        binsizes = list( map(cmp.resolutionToBinsize, self.resolutions)  )
        binsizes = sorted( binsizes )
        self.chromResolutionListWidget.addItems( list( map(cmp.binsizeToResolution, binsizes)  ) )

    def resolutionSelector(self):
        """ To display/change resolution list when a chromosome is selected by user
        """

        if self.chromResolutionListWidget.currentItem() is None : return

        # Removing dataNames list
        if self.dataNames is not None:
            for i in range(len(self.dataNames)):
                dummy = self.dataNameListWidget.takeItem(0)
                del dummy

            self.dataNames = None

        # Generating dataNames list
        self.dataNames = []
        currentChrom = self.chromNameListWidget.currentItem().text()
        currentResolution = self.chromResolutionListWidget.currentItem().text()
        for key in self.data[currentChrom][currentResolution]:
            if key in self.coarse_methods_name:
                self.dataNames.append(self.coarse_methods_name[key])
            else:
                self.dataNames.append(key)

        self.dataNameListWidget.addItems(sorted(self.dataNames))

    def on_button_clicked(self, button):
        """Do when Open/Abort button is clicked
        """
        if button.text() == "Open":
            if self.dataNameListWidget.currentItem() is not None:
                chroms = self.chromNameListWidget.currentItem().text()
                resolution = self.chromResolutionListWidget.currentItem().text()
                dataType = self.dataNameListWidget.currentItem().text()

                # In case if resolution of map not match with genomic dataset
                if self.requestedBinsize is not None:
                    requestedResolution = cmp.binsizeToResolution(self.requestedBinsize)
                    if resolution != requestedResolution:
                        msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'Selected resolution "{0}" does not match with map resolution "{1}" .'
                                                     .format(resolution, requestedResolution),QMessageBox.Ok, self)
                        msgBox.exec_()
                        msgBox.close()
                        return

                if dataType in self.coarse_methods_name_r:
                    self.selected_data = (chroms, resolution, self.coarse_methods_name_r[dataType])
                else:
                    self.selected_data = (chroms, resolution, dataType)
                self.whereToPlot = self.plotAtComboBox.currentText().lower()
                self.accept()

        if button.text() == "Abort":
            self.reject()


# Dialog box to select and load genomic data from text file
pathToThisUI = os.path.join(PathToUIs, 'textFileSelector.ui')
Ui_DialogTextFileSelector, QDialogTextFileSelectorBase = loadUiType(pathToThisUI)
class DialogTextFileSelector(QDialogTextFileSelectorBase, Ui_DialogTextFileSelector):
    def __init__(self, inputFileName=None):
        super(DialogTextFileSelector, self).__init__()
        self.setupUi(self)

        self.inputFileName = inputFileName
        self.plotPosition = None
        self.title = str( self.titleLineEdit.text() )

        if self.inputFileName is not None:
            self.fileNameLineEdit.setText(self.inputFileName)

        self.openFileButton.setIcon( self.style().standardIcon(QStyle.SP_DirOpenIcon) )

        self.fileNameLineEdit.editingFinished.connect(self.checkInputFile)
        self.titleLineEdit.editingFinished.connect( self.checkTitle )

        self.openFileButton.clicked.connect( self.browseFile )
        self.okCancelButtons.clicked.connect(self.onOkCancelButtonsClicked)

    def browseFile(self):
        """Browse and select input text file
        """
        # A dialog box will be displayed to select a text file and path will be stored in the cell
        file_choices = " text file (*.txt *.dat)"
        path = QFileDialog.getOpenFileName(self, 'Select a text file', '', file_choices)
        if path[0]:
            self.fileNameLineEdit.setText( path[0] )

    def checkInputFile(self):
        """Check input file exist
        """
        inputFile = str( self.fileNameLineEdit.text() )
        if inputFile and not os.path.isfile(inputFile):
            self.fileNameLineEdit.clear()

    def checkTitle(self):
        """Check title of the file"""
        title =  str( self.titleLineEdit.text() )
        if not title:
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'No title! Title should be present.', QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()
            self.titleLineEdit.setText( self.title )
        else:
            self.title = title

    def parseDisplayedOptions(self):
        """Parse all options displayed on dialog
        """
        # If input file name store it or return 0
        inputFileName = str( self.fileNameLineEdit.text() )
        if inputFileName:
            self.inputFileName = inputFileName
        else:
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'No input text file selected.', QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()
            self.inputFileName = None
            return 0

        # Store plot position
        if self.plotPositionCBox.currentIndex() == 0:
            self.plotPosition = 'bottom'
        else:
            self.plotPosition = 'top'

        return 1

    def onOkCancelButtonsClicked(self, button):
        """Do when final OK or Cancel buttons are clicked by user
        """
        if button.text() == 'OK':
            if self.parseDisplayedOptions():
                self.done(QDialog.Accepted)
            else:
                return
        if button.text() == 'Cancel':
            self.done(QDialog.Rejected)

# Dialog box to choose and load genomic data
pathToThisUI = os.path.join(PathToUIs, 'correlationMaps.ui')
Ui_DialogCorrelationMaps, QDialogCorrelationMapsBase = loadUiType(pathToThisUI)
class DialogCorrelationBetweenMaps(QDialogCorrelationMapsBase, Ui_DialogCorrelationMaps):
    def __init__(self):
        super(DialogCorrelationBetweenMaps, self).__init__()
        self.setupUi(self)

        self.hicmapList = None
        self.firstMap = None
        self.secondMap = None
        self.firstHicmap = None
        self.secondHicmap = None
        self.ignore_triangular = None
        self.diagonal_offset = None
        self.corrType = None
        self.blockSize = None
        self.workDir = None
        self.slideStepSize = None

        # Results
        self.corr = None
        self.aux = None

        # calculating Thread
        self.thread = None
        self.que = None

        # Set default icons for buttons
        self.set_icons()

        # Set default working directory
        self.setDefaultWorkingDirectory()

        # Set loogger handler to a new type
        self.loggerHandler = guiHelpers.pyQtLogHandler()
        self.loggerHandler.messageEmitted.connect( self.loggerPlainTextEdit.appendPlainText ) # Connect loggerHandler to log textbox


        # Set validator for lineedit boxes
        self.diagOffsetLineEdit.setValidator(QIntValidator())
        self.slideStepSizeLineEdit.setValidator(QIntValidator())

        # Connect browse buttons for input ccmap
        self.firstMapBrowsButton.clicked.connect(self.browseFirstMap)
        self.secondMapBrowsButton.clicked.connect(self.browseSecondMap)
        self.workDirBrowseButton.clicked.connect( self.browseWorkingDirectory )

        # check input ccmap line-edits for valid file
        self.firstMapInputLineEdit.editingFinished.connect(self.checkInputMapFiles)
        self.secondMapInputLineEdit.editingFinished.connect(self.checkInputMapFiles)
        self.workDirLineEdit.editingFinished.connect( self.checkWorkDirExist )

        # Connect other remaining buttons
        self.calculateButton.clicked.connect( self.calculate )
        self.stopButton.clicked.connect( self.terminateThread )
        self.closeButton.clicked.connect( self.closeDialog )
        self.saveOutputButton.clicked.connect( self.saveOutput )
        self.clearOutputButton.clicked.connect( self.outputTextEdit.clear )

    def addHicmaps(self, ccmap, title):
        """Add hicmaps
        """
        if self.hicmapList is None:
            self.hicmapList = []
            self.firstMapInputCBox.setItemText(0, title)
            self.secondMapInputCBox.setItemText(0, title)
        else:
            self.firstMapInputCBox.addItem(title)
            self.secondMapInputCBox.addItem(title)

        self.hicmapList.append(ccmap)

    def set_icons(self):
        """Set standard file icon to browse buttons
        """
        self.firstMapBrowsButton.setIcon( self.style().standardIcon(QStyle.SP_DirOpenIcon) )
        self.secondMapBrowsButton.setIcon( self.style().standardIcon(QStyle.SP_DirOpenIcon) )
        self.workDirBrowseButton.setIcon( self.style().standardIcon(QStyle.SP_DirOpenIcon) )

    def setDefaultWorkingDirectory(self):
        """Set default working directory and self.workDir
        """
        self.workDir = tempfile.gettempdir()
        self.workDirLineEdit.setText(self.workDir)

    def browseWorkingDirectory(self):
        """Browse and choose working directory
        """
        path = QFileDialog.getExistingDirectory(self, 'Select Working Directory', os.getcwd() )
        if path:
            self.workDirLineEdit.setText(path)

    def checkWorkDirExist(self):
        """To check if working directory exists
        """
        workDir = str( self.workDirLineEdit.text() )
        if workDir and os.path.isdir(workDir):
            self.workDir = workDir
        else:
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'Directoy: {0} not found!!'.format(workDir), QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()
            self.workDirLineEdit.setText( self.workDir )

    def browseFirstMap(self):
        """Browse and select first ccmap file
        """
        # A dialog box will be displayed to select a text file and path will be stored in the cell
        file_choices = " ccmap file (*.ccmap)"
        path = QFileDialog.getOpenFileName(self, 'Load File', '', file_choices)
        if path[0]:
            self.firstMapInputLineEdit.setText( path[0] )

    def browseSecondMap(self):
        """Browse and select second ccmap file
        """
        # A dialog box will be displayed to select a text file and path will be stored in the cell
        file_choices = " ccmap file (*.ccmap)"
        path = QFileDialog.getOpenFileName(self, 'Load File', '', file_choices)
        if path[0]:
            self.secondMapInputLineEdit.setText( path[0] )

    def checkInputMapFiles(self):
        """Check input ccmap file is exist
        """
        mapFile = str( self.firstMapInputLineEdit.text() )
        if mapFile and not os.path.isfile(mapFile):
            self.firstMapInputLineEdit.clear()

        mapFile = str( self.secondMapInputLineEdit.text() )
        if mapFile and not os.path.isfile(mapFile):
            self.secondMapInputLineEdit.clear()

    def parseDisplayedOptions(self):
        """Parse and store all displayed options in dialog box

        It should return 1 if everything is parsed successfully.

        """

        # Check for first input ccmap
        if self.firstMapInputCBox.currentText() == 'Not Available':
            firstMap = str( self.firstMapInputLineEdit.text() )
            if firstMap:
                self.firstMap = firstMap
            elif self.hicmapList is not None:
                pass
            else:
                msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'Please select first ccmap', QMessageBox.Ok, self)
                msgBox.exec_()
                msgBox.close()
                self.firstMap = None
                return 0

        # Check for second input ccmap
        secondMap = str( self.secondMapInputLineEdit.text() )
        if secondMap:
            self.secondMap = secondMap
        elif self.hicmapList is not None:
            pass
        else:
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'Please select second ccmap', QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()
            self.secondMap = None
            return 0

        # Check for ignore_triangular option
        if self.ignoreTriangularCBox.currentIndex() == 0:
            self.ignore_triangular = True
        else:
            self.ignore_triangular = False

        # Check for diagonal offset option
        diagonal_offset = int( self.diagOffsetLineEdit.text() )
        if diagonal_offset:
            self.diagonal_offset = diagonal_offset
        else:
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'No offset from Diagonal. Setting it to zero.', QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()
            self.diagonal_offset = 0

        # Check for correlation type option
        if self.corrTypeCBox.currentIndex() == 0:
            self.corrType = 'pearson'
        else:
            self.corrType = 'spearman'

        # Check for block-size option
        if self.blockGBox.isChecked():
            resolution = self.sizeBlockLineEdit.text()
            if resolution:
                try:
                    cmp.resolutionToBinsize(resolution)
                except ValueError:
                    msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'Resolution should be in kb or mb.', QMessageBox.Ok, self)
                    msgBox.exec_()
                    msgBox.close()
                    return 0
                self.blockSize = resolution
        else:
            self.blockSize = None

        # Check for slide step size option
        if int(self.slideStepSizeLineEdit.text()) > 0:
            self.slideStepSize = int(self.slideStepSizeLineEdit.text())
        else:
            msgBox = QMessageBox(QMessageBox.Warning, 'Warning', 'Slide step size should be larger than zero', QMessageBox.Ok, self)
            msgBox.exec_()
            msgBox.close()
            self.slideStepSizeLineEdit.setText('1')
            return 0

        return 1

    def loadCCMAP(self):
        """Load hicmaps from input ccmap files
        """
        if self.firstMap is not None:
            self.firstHicmap = cmp.load_hicmap(self.firstMap)
            self.firstHicmap.make_readable()
        else:
            self.firstHicmap = self.hicmapList[ self.firstMapInputCBox.currentIndex() ]

        if self.secondMap is not None:
            self.secondHicmap = cmp.load_hicmap(self.secondMap)
            self.secondHicmap.make_readable()
        else:
            self.secondHicmap = self.hicmapList[ self.secondMapInputCBox.currentIndex() ]

    def calculate(self, checked):
        """Perform final calculation and display result in output box
        """
        # Check if user has given correct options otherwise return
        if not self.parseDisplayedOptions():    return

        if checked:
            # Clear all text edit boxes at the start of calculation
            self.outputTextEdit.clear()
            self.loggerPlainTextEdit.clear()

            # Load hicmaps
            self.loadCCMAP()

            # Keywords arguments for correlateHicMaps
            kwargs = { 'ignore_triangular':self.ignore_triangular, 'diagonal_offset':self.diagonal_offset, 'corrType':self.corrType,
                        'blockSize':self.blockSize, 'slideStepSize':self.slideStepSize, 'workDir':self.workDir, 'logHandler':self.loggerHandler }

            # Initialize a new thread and connect it
            self.thread = guiHelpers.qtThread(target=cmstats.correlateCMaps, args=(self.firstHicmap, self.secondHicmap), kwargs=kwargs)
            self.thread.resultReady.connect( self.finishedCalculation )

            # Start the thread
            self.thread.start()

            # Change states of buttons on GUI
            self.stopButton.setEnabled(True)
            self.calculateButton.setEnabled(False)

    def finishedCalculation(self):
        """When calculation is finished
        """
        # Uncheck the calculate button
        self.calculateButton.setChecked(False)

        # If thread is still alive, particulary when calculation is properly finished but not terminated abruptly
        if self.thread is not None:

            # Write results to ouput text box
            corr, aux = self.thread.results
            if self.blockSize is None:
                self.outputTextEdit.appendPlainText('Correlation: {0}'.format(corr))
                self.outputTextEdit.appendPlainText('p value: {0}'.format(aux))
            else:
                for i in range(len(corr)):
                    if corr[i] != 0:
                        self.outputTextEdit.appendPlainText('{0}\t{1}'.format(int(aux[i]), corr[i]))

            # Close thread and remove from memory
            self.thread.wait()
            self.thread.quit()
            del self.thread
            self.thread = None

            # set states of button on GUI
            self.stopButton.setEnabled(False)
            self.calculateButton.setEnabled(True)

    def terminateThread(self):
        """When calculation is stopped abruptly
        """
        # disable stop button
        self.stopButton.setEnabled(False)
        self.loggerPlainTextEdit.appendPlainText('Wait, trying to stopping calculation...')      # Write message in log box
        QApplication.processEvents()                                                             # Update events on GUI
        if self.thread is None: return
        self.thread.requestInterruption()   # Request for thread interruption. Terminate does not work.
        self.thread.wait()                  # Wait to terminate the thread
        del self.thread                     # remove the thread completely from memory
        self.loggerPlainTextEdit.appendPlainText('Calculation stopped.')    # Update status in log box
        self.thread = None
        self.calculateButton.setEnabled(True)

    def closeDialog(self):
        """Close this dialog
        """
        self.reject()

    def saveOutput(self):
        """Save output as file from output box
        """
        # A dialog box will be displayed to select a text file and path will be stored in the cell
        file_choices = " text file (*.txt *.dat)"
        path = QFileDialog.getSaveFileName(self, 'Save Output File', '', file_choices)
        if path[0]:
            outfile = path[0]
            ext = os.path.splitext(outfile)[1]
            if not (ext == '.txt' or ext == '.dat'):
                outfile += '.txt'
            fout = open(outfile, 'w')
            fout.write(self.outputTextEdit.toPlainText())
            fout.close()


class AxesProperties:
    ''' Used to hold and change axis properties.
    '''
    def __init__(self, axes, xTickLocations=None, xTickLabelTexts=None, yTickLocations=None, yTickLabelTexts=None):
        self.axes = axes
        self.xTickLocations = xTickLocations
        self.xTickLabelTexts = xTickLabelTexts
        self.yTickLocations = yTickLocations
        self.yTickLabelTexts = yTickLabelTexts

        # Initialize axes proeprties dictionary
        self.xLabel = self.init_xlabel_dict()
        self.yLabel = self.init_yLabel_dict()
        self.xTickLabel = self.init_xTickLabel_dict()
        self.yTickLabel = self.init_yTickLabel_dict()

        self.get_from_axes()

    def init_xlabel_dict(self):
        xLabel = dict()
        xLabel['Text'] = None
        xLabel['Show Label'] = None
        xLabel['Font Name'] = None
        xLabel['Font Size'] = None
        xLabel['padding'] = None
        return xLabel

    def init_yLabel_dict(self):
        yLabel = dict()
        yLabel['Text'] = None
        yLabel['Show Label'] = None
        yLabel['Font Name'] = None
        yLabel['Font Size'] = None
        yLabel['padding'] = None
        return yLabel

    def init_xTickLabel_dict(self):
        xTickLabel = dict()
        xTickLabel['Label Position'] = None
        xTickLabel['Label Rotation'] = None
        xTickLabel['Font Name'] = None
        xTickLabel['Font Size'] = None
        xTickLabel['padding'] = None

        xTickLabel['Tick Intervals'] = None
        xTickLabel['Tick Position'] = None
        xTickLabel['Major Ticks Length'] = None
        xTickLabel['Major Ticks Width'] = None
        xTickLabel['Minor Ticks Visible'] = None
        xTickLabel['Minor Ticks Length'] = None
        xTickLabel['Minor Ticks Width'] = None
        return xTickLabel

    def init_yTickLabel_dict(self):
        yTickLabel = dict()
        yTickLabel['Label Position'] = None
        yTickLabel['Label Rotation'] = None
        yTickLabel['Font Name'] = None
        yTickLabel['Font Size'] = None
        yTickLabel['padding'] = None

        yTickLabel['Tick Intervals'] = None
        yTickLabel['Tick Position'] = None
        yTickLabel['Major Ticks Length'] = None
        yTickLabel['Major Ticks Width'] = None
        yTickLabel['Minor Ticks Visible'] = None
        yTickLabel['Minor Ticks Length'] = None
        yTickLabel['Minor Ticks Width'] = None
        return yTickLabel

    def modify_xtick_intervals(self, num_tick_intervals):

        # Do not apply setting when no input is given
        if self.xTickLocations is None: return

        # Original range shown on axis
        view_interval = self.axes.get_xaxis().get_view_interval()

        # Try to change interval with nice tick locations. Sometimes changes, some time not.
        major_locator = MaxNLocator(nbins=num_tick_intervals)
        self.axes.get_xaxis().set_major_locator(major_locator)
        self.axes.get_xaxis().set_view_interval(view_interval[0], view_interval[1])

        # Removing any xticks outside the original intervals
        xticks = list(self.axes.get_xticks())
        while(1):
            if xticks[0] <  view_interval[0]:
                del xticks[0]
            else:
                break

        while(1):
            if xticks[-1] >  view_interval[1]:
                del xticks[-1]
            else:
                break

        # Resetting ticks interval
        self.axes.set_xticks(xticks)

        # Change tick labels if required
        if self.xTickLabelTexts is None:
            self.axes.set_xticklabels(self.axes.get_xticks())
        else:
            # Check whther ticks locations and tick labels are compaitable
            if len(self.xTickLocations) != len(self.xTickLabelTexts):
                raise AssertionError ('Number of x-axis locations you provided do not match with number of xticklabels')

            # Retrive indices of tick labels corresponding to ticks and make list of labels
            xticks = self.axes.get_xticks()
            ticklabels = []
            for xtick in xticks:
                idx = np.argmin( np.abs(self.xTickLocations - xtick) )
                ticklabels.append(self.xTickLabelTexts[idx])

            self.axes.set_xticklabels(ticklabels)

    def modify_ytick_intervals(self, num_tick_intervals):


        # Original range shown on axis
        view_interval = self.axes.get_yaxis().get_view_interval()

        # Try to change interval with nice tick locations. Sometimes changes, some time not.
        major_locator = MaxNLocator(nbins=num_tick_intervals)
        self.axes.get_yaxis().set_major_locator(major_locator)
        self.axes.get_yaxis().set_view_interval(view_interval[0], view_interval[1])

        # Removing any xticks outside the original intervals
        yticks = list(self.axes.get_yticks())
        while(1):
            if yticks[0] <  view_interval[0]:
                del yticks[0]
            else:
                break

        while(1):
            if yticks[-1] >  view_interval[1]:
                del yticks[-1]
            else:
                break

        # Resetting ticks interval
        self.axes.set_yticks(yticks)

        # Do not apply setting when no input is given
        if self.yTickLocations is None: return

        # Change tick labels if required
        if self.yTickLabelTexts is None:
            self.axes.set_yticklabels(self.axes.get_yticks())
        else:
            # Check whther ticks locations and tick labels are compaitable
            if len(self.yTickLocations) != len(self.yTickLabelTexts):
                raise AssertionError ('Number of y-axis locations do not match with number of yticklabels')

            # Retrive indices of tick labels corresponding to ticks and make list of labels
            yticks = self.axes.get_yticks()
            ticklabels = []
            for ytick in yticks:
                idx = np.argmin( np.abs(self.yTickLocations - ytick) )
                ticklabels.append(self.yTickLabelTexts[idx])

            self.axes.set_yticklabels(ticklabels)

    def getXLabelPropsFromAxes(self):
        ''' Get X-label properties from the axes instant
        '''
        self.xLabel['Text'] = self.axes.get_xaxis().get_label_text()
        self.xLabel['Show Label'] = self.axes.get_xaxis().get_label_position()
        if not self.axes.get_xaxis().get_label().get_visible():
            self.xLabel['Show Label'] = 'none'
        self.xLabel['Font Name'] = self.axes.get_xaxis().get_label().get_fontname()
        self.xLabel['Font Size'] = int( self.axes.get_xaxis().get_label().get_fontsize() )
        self.xLabel['padding'] = self.axes.xaxis.labelpad

    def getYLabelPropsFromAxes(self):
        ''' Get Y-label properties from the axes instant
        '''
        self.yLabel['Text'] = self.axes.get_yaxis().get_label_text()
        self.yLabel['Show Label'] = self.axes.get_yaxis().get_label_position()
        if not self.axes.get_yaxis().get_label().get_visible():
            self.yLabel['Show Label'] = 'none'
        self.yLabel['Font Name'] = self.axes.get_yaxis().get_label().get_fontname()
        self.yLabel['Font Size'] = int( self.axes.get_yaxis().get_label().get_fontsize() )
        self.yLabel['padding'] = self.axes.yaxis.labelpad

    def getXTickLabelPropsFromAxes(self):
        # Tick position and Tick-label position
        ticks = self.axes.get_xaxis().get_major_ticks()

        # Getting ticks position
        if ticks[0].tick1On and ticks[0].tick2On:
            self.xTickLabel['Tick Position'] = 'both'
        if ticks[0].tick1On and not ticks[0].tick2On:
            self.xTickLabel['Tick Position'] = 'bottom'
        if not ticks[0].tick1On and ticks[0].tick2On:
            self.xTickLabel['Tick Position'] = 'top'
        if not ticks[0].tick1On and not ticks[0].tick2On:
            self.xTickLabel['Tick Position'] = 'none'

        # Getting tick-labels position
        if ticks[0].label1On and ticks[0].label2On:
            self.xTickLabel['Label Position'] = 'both'
        if ticks[0].label1On and not ticks[0].label2On:
            self.xTickLabel['Label Position'] = 'bottom'
        if not ticks[0].label1On and ticks[0].label2On:
            self.xTickLabel['Label Position'] = 'top'
        if not ticks[0].label1On and not ticks[0].label2On:
            self.xTickLabel['Label Position'] = 'none'

        #Getting tick-label padding
        self.xTickLabel['padding'] = ticks[0].get_pad()


        self.xTickLabel['Minor Ticks Visible'] = bool( self.axes.get_xaxis().get_minor_ticks() )
        # Get number of minor ticks if it is present
        if self.xTickLabel['Minor Ticks Visible']:
            self.xTickLabel['Minor Ticks Visible'] = len(self.axes.get_xaxis().get_minor_ticks()) / ( len(self.axes.get_xaxis().get_major_ticks()) -1 )

        # Major tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_xaxis().get_majorticklines()
        if ticklines:
            self.xTickLabel['Major Ticks Length'] = ticklines[0].get_markersize()
            self.xTickLabel['Major Ticks Width'] = ticklines[0].get_markeredgewidth()

        # Minor tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_xaxis().get_minorticklines()
        if ticklines:
            self.xTickLabel['Minor Ticks Length'] = ticklines[0].get_markersize()
            self.xTickLabel['Minor Ticks Width'] = ticklines[0].get_markeredgewidth()

        # Tick labels font-name, font-size and rotations
        if self.xTickLabel['Label Position'] != 'none':
            labels = self.axes.get_xticklabels()
            self.xTickLabel['Font Name'] = labels[0].get_fontname()
            self.xTickLabel['Font Size'] = int( labels[0].get_fontsize() )
            self.xTickLabel['Label Rotation'] = int( labels[0].get_rotation() )

        # Getting number of tick intervals
        if self.xTickLabel['Tick Intervals'] is None:
            self.xTickLabel['Tick Intervals'] = len(self.axes.get_xticks()) - 1

    def getYTickLabelPropsFromAxes(self):
        # Tick position and Tick-label position
        ticks = self.axes.get_yaxis().get_major_ticks()

        # Getting ticks position
        if ticks[0].tick1On and ticks[0].tick2On:
            self.yTickLabel['Tick Position'] = 'both'
        if ticks[0].tick1On and not ticks[0].tick2On:
            self.yTickLabel['Tick Position'] = 'left'
        if not ticks[0].tick1On and ticks[0].tick2On:
            self.yTickLabel['Tick Position'] = 'right'
        if not ticks[0].tick1On and not ticks[0].tick2On:
            self.yTickLabel['Tick Position'] = 'none'

        # Getting tick-labels position
        if ticks[0].label1On and ticks[0].label2On:
            self.yTickLabel['Label Position'] = 'both'
        if ticks[0].label1On and not ticks[0].label2On:
            self.yTickLabel['Label Position'] = 'left'
        if not ticks[0].label1On and ticks[0].label2On:
            self.yTickLabel['Label Position'] = 'right'
        if not ticks[0].label1On and not ticks[0].label2On:
            self.yTickLabel['Label Position'] = 'none'

        #Getting tick-label padding
        self.yTickLabel['padding'] = ticks[0].get_pad()

        self.yTickLabel['Minor Ticks Visible'] = bool( self.axes.get_yaxis().get_minor_ticks() )
        # Get number of minor ticks if it is present
        if self.yTickLabel['Minor Ticks Visible']:
            self.yTickLabel['Minor Ticks Visible'] = len(self.axes.get_yaxis().get_minor_ticks()) / ( len(self.axes.get_yaxis().get_major_ticks()) -1 )

        # Major tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_yaxis().get_majorticklines()
        if ticklines:
            self.yTickLabel['Major Ticks Length'] = ticklines[0].get_markersize()
            self.yTickLabel['Major Ticks Width'] = ticklines[0].get_markeredgewidth()

        # Minor tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_yaxis().get_minorticklines()
        if ticklines:
            self.yTickLabel['Minor Ticks Length'] = ticklines[0].get_markersize()
            self.yTickLabel['Minor Ticks Width'] = ticklines[0].get_markeredgewidth()

        # Tick labels font-name, font-size and rotations
        if self.yTickLabel['Label Position'] != 'none':
            labels = self.axes.get_yticklabels()
            self.yTickLabel['Font Name'] = labels[0].get_fontname()
            self.yTickLabel['Font Size'] = int( labels[0].get_fontsize() )
            self.yTickLabel['Label Rotation'] = int( labels[0].get_rotation() )

        # Getting number of tick intervals
        if self.yTickLabel['Tick Intervals'] is None:
            self.yTickLabel['Tick Intervals'] = len(self.axes.get_yticks()) - 1

    def setXLabelPropsToAxes(self):
        ''' Get X-label properties from the axes instant
        '''
        self.axes.get_xaxis().set_label_text(self.xLabel['Text'])
        if self.xLabel['Show Label'] == 'none':
            self.axes.get_xaxis().get_label().set_visible(False)
        else:
            self.axes.get_xaxis().set_label_position(self.xLabel['Show Label'])
        self.axes.get_xaxis().get_label().set_fontname(self.xLabel['Font Name'])
        self.axes.get_xaxis().get_label().set_fontsize(self.xLabel['Font Size'])
        self.axes.xaxis.labelpad = self.xLabel['padding']

    def setYLabelPropsToAxes(self):
        self.axes.get_yaxis().set_label_text(self.yLabel['Text'])
        if self.yLabel['Show Label'] == 'none':
            self.axes.get_yaxis().get_label().set_visible(False)
        else:
            self.axes.get_yaxis().set_label_position(self.yLabel['Show Label'])
        self.axes.get_yaxis().get_label().set_fontname(self.yLabel['Font Name'])
        self.axes.get_yaxis().get_label().set_fontsize(self.yLabel['Font Size'])
        self.axes.yaxis.labelpad = self.yLabel['padding']

    def setXTickLabelPropsToAxes(self):
        # Setting minor ticks
        if self.xTickLabel['Minor Ticks Visible']:
            # Setting minor locator
            minorLocator = AutoMinorLocator( self.xTickLabel['Minor Ticks Visible'] + 1 )
            self.axes.get_xaxis().set_minor_locator(minorLocator)

        # Tick position and Tick-label position
        ticks = self.axes.get_xaxis().get_major_ticks()
        if self.xTickLabel['Minor Ticks Visible']:
            ticks = ticks + self.axes.get_xaxis().get_minor_ticks()

        if self.xTickLabel['Tick Position'] == 'both':
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = True
        if self.xTickLabel['Tick Position'] == 'bottom':
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = False
        if self.xTickLabel['Tick Position'] == 'top':
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = True
        if self.xTickLabel['Tick Position'] == 'none':
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = False

        ticks = self.axes.get_xaxis().get_major_ticks()
        if self.xTickLabel['Label Position'] == 'both':
            for tick in ticks:
                tick.label1On = True
                tick.label2On = True
        if self.xTickLabel['Label Position'] == 'bottom':
            for tick in ticks:
                tick.label1On = True
                tick.label2On = False
        if self.xTickLabel['Label Position'] == 'top':
            for tick in ticks:
                tick.label1On = False
                tick.label2On = True
        if self.xTickLabel['Label Position'] == 'none':
            for tick in ticks:
                tick.label1On = False
                tick.labelOn = False

        #Setting tick-label padding
        self.axes.xaxis.set_tick_params(pad=self.xTickLabel['padding'])

        # Major tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_xaxis().get_majorticklines()
        if ticklines:
            for tickline in ticklines:
                tickline.set_markersize(self.xTickLabel['Major Ticks Length'])
                tickline.set_markeredgewidth(self.xTickLabel['Major Ticks Width'])


        # Tick labels font-name, font-size and rotations
        labels = self.axes.get_xticklabels()
        for label in labels:
            label.set_fontname(self.xTickLabel['Font Name'])
            label.set_fontsize(self.xTickLabel['Font Size'])
            label.set_rotation(self.xTickLabel['Label Rotation'])

        # Getting number of tick intervals
        self.modify_xtick_intervals(self.xTickLabel['Tick Intervals'])

        # Minor tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_xaxis().get_minorticklines()
        if ticklines:
            for tickline in ticklines:
                tickline.set_markersize(self.xTickLabel['Minor Ticks Length'])
                tickline.set_markeredgewidth(self.xTickLabel['Minor Ticks Width'])

    def setYTickLabelPropsToAxes(self):
        # Setting minor ticks
        if self.yTickLabel['Minor Ticks Visible']:
            # Setting minor locator
            minorLocator = AutoMinorLocator( self.yTickLabel['Minor Ticks Visible'] + 1 )
            self.axes.get_yaxis().set_minor_locator(minorLocator)

        # Tick position and Tick-label position
        ticks = self.axes.get_yaxis().get_major_ticks()
        if self.yTickLabel['Minor Ticks Visible']:
            ticks = ticks + self.axes.get_yaxis().get_minor_ticks()

        if self.yTickLabel['Tick Position'] == 'both':
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = True
        if self.yTickLabel['Tick Position'] == 'left':
            for tick in ticks:
                tick.tick1On = True
                tick.tick2On = False
        if self.yTickLabel['Tick Position'] == 'right':
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = True
        if self.yTickLabel['Tick Position'] == 'none':
            for tick in ticks:
                tick.tick1On = False
                tick.tick2On = False

        ticks = self.axes.get_yaxis().get_major_ticks()
        if self.yTickLabel['Label Position'] == 'both':
            for tick in ticks:
                tick.label1On = True
                tick.label2On = True
        if self.yTickLabel['Label Position'] == 'left':
            for tick in ticks:
                tick.label1On = True
                tick.label2On = False
        if self.yTickLabel['Label Position'] == 'right':
            for tick in ticks:
                tick.label1On = False
                tick.label2On = True
        if self.yTickLabel['Label Position'] == 'none':
            for tick in ticks:
                tick.label1On = False
                tick.labelOn = False

        #Setting tick-label padding
        self.axes.yaxis.set_tick_params(pad=self.yTickLabel['padding'])

        # Major tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_yaxis().get_majorticklines()
        if ticklines:
            for tickline in ticklines:
                tickline.set_markersize(self.yTickLabel['Major Ticks Length'])
                tickline.set_markeredgewidth(self.yTickLabel['Major Ticks Width'])


        # Tick labels font-name, font-size and rotations
        labels = self.axes.get_yticklabels()
        for label in labels:
            label.set_fontname(self.yTickLabel['Font Name'])
            label.set_fontsize(self.yTickLabel['Font Size'])
            label.set_rotation(self.yTickLabel['Label Rotation'])

        # Getting number of tick intervals
        self.modify_ytick_intervals(self.yTickLabel['Tick Intervals'])

        # Minor tick lines: ticklines is a list of 2D Line objects
        ticklines = self.axes.get_yaxis().get_minorticklines()
        if ticklines:
            for tickline in ticklines:
                tickline.set_markersize(self.yTickLabel['Minor Ticks Length'])
                tickline.set_markeredgewidth(self.yTickLabel['Minor Ticks Width'])

    def get_from_axes(self):
        # getting axes properties
        self.getXLabelPropsFromAxes()
        self.getYLabelPropsFromAxes()
        self.getXTickLabelPropsFromAxes()
        self.getYTickLabelPropsFromAxes()

    def set_to_axes(self):
        self.setXLabelPropsToAxes()
        self.setYLabelPropsToAxes()
        self.setXTickLabelPropsToAxes()
        self.setYTickLabelPropsToAxes()


class menuRightClick(QMenu):
    def __init__(self, ):
        super(menuRightClick, self).__init__()
        self.actionList = dict()
        self.addSubMenus()

    def addSubMenus(self):
        self.actionXlabel = self.addAction("Edit X-axis Label...")
        self.actionList[0] = self.actionXlabel
        self.actionYlabel = self.addAction("Edit Y-axis Label...")
        self.actionList[1] = self.actionYlabel
        self.actionXtickLabel = self.addAction("Edit X-ticks Label...")
        self.actionList[2] = self.actionXtickLabel
        self.actionYtickLabel = self.addAction("Edit Y-ticks Label...")
        self.actionList[3] = self.actionYtickLabel


def add_colormaps_to_combobox(cbox):
    cmap_lists = [ 'afmhot_r', 'autumn_r', 'bone_r', 'cool_r', 'copper_r',
                  'gist_heat_r', 'gray_r', 'hot_r', 'pink_r', 'spring_r', 'summer_r', 'winter_r', 'Blues',
                  'BuGn', 'BuPu', 'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd', 'PuBu', 'PuBuGn', 'PuRd',
                  'Purples', 'RdPu', 'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd',
                  'afmhot', 'autumn', 'bone', 'cool', 'copper', 'gist_heat', 'gray', 'hot', 'pink',
                   'spring', 'summer', 'winter', ]

    cmap_icons = ['afmhot_r.ico', 'autumn_r.ico', 'bone_r.ico', 'cool_r.ico', 'copper_r.ico',
                  'gist_heat_r.ico', 'gray_r.ico', 'hot_r.ico', 'pink_r.ico', 'spring_r.ico', 'summer_r.ico', 'winter_r.ico', 'blues.ico',
                  'blue_green.ico', 'blue_purple.ico', 'green_blue.ico', 'greens.ico', 'greys.ico', 'oranges.ico', 'oranges_red.ico', 'purple_blue.ico', 'purple_blue_green.ico',
                  'purple_red.ico', 'purples.ico', 'red_purples.ico', 'reds.ico', 'yellow_green.ico', 'yellow_green_blue.ico', 'yellow_orange_brown.ico', 'yellow_orange_red.ico',
                  'afmhot.ico', 'autumn.ico', 'bone.ico', 'cool.ico', 'copper.ico', 'gist_heat.ico', 'gray.ico', 'hot.ico', 'pink.ico',
                  'spring.ico', 'summer.ico', 'winter.ico',  ]

    icon_path = os.path.join(DirToThisScript, 'icons')
    icon_path = os.path.join(icon_path, 'cmaps')

    cmap = dict()
    for i in range(len(cmap_lists)):
        cmap[i] = cmap_lists[i]

    for i in range(len(cmap_lists)):
        qicon = QIcon()
        icon_file = os.path.join(icon_path, cmap_icons[i])
        qicon.addFile(icon_file)
        cbox.addItem(qicon, cmap_lists[i])

    cbox.setCurrentIndex(6)

    return cmap

def scaleMatrix(matrix, vmin, vmax):
    # Masked the matrix for zero values
    maskedMatrix = np.ma.masked_equal(matrix, 0.0, copy=False)

    scaledMatrix = (maskedMatrix - maskedMatrix.min()) / (maskedMatrix.max() - maskedMatrix.min())

    scaledMatrix = scaledMatrix * (vmax - vmin) + vmin

    return scaledMatrix.filled(0.0)


def add_icon_to_widget(widget, icon_file):
    qicon = QIcon()
    icon_path = os.path.join(DirToThisScript, 'icons')
    icon_file = os.path.join(icon_path, icon_file)
    qicon.addFile(icon_file)
    widget.setIcon(qicon)

def HLine():
    frame = QFrame()
    frame.setFrameShape(QFrame.HLine)
    frame.setFrameShadow(QFrame.Sunken)
    return frame

def VLine():
    frame = QFrame()
    frame.setFrameShape(QFrame.VLine)
    frame.setFrameShadow(QFrame.Sunken)
    return frame

def get_interpolation_dict():
    method = ['none', 'nearest', 'bilinear', 'sinc', 'lanczos', 'bicubic', 'gaussian', 'spline16', 'spline36', 'hanning', 'hamming',
              'hermite', 'kaiser', 'quadric', 'catrom', 'bessel', 'mitchell']

    interpolation = dict()
    for i in range(len(method)):
        interpolation[i] = method[i]

    return interpolation
