# -*- coding: utf-8 -*-
"""
l'application winwii

$Id$
$URL$
"""

import pygame
from pgu.gui import Desktop
from pgu.gui import QUIT
from minwii.widgets.launch import LaunchScreen
from minwii.widgets.home import Home
from minwii.widgets.playingscreen import SongPlayingScreen, PlayingScreen
from minwii.widgets.instrumentselector import InstrumentSelector
from minwii.synth import Synth
from minwii.eventutils import EventDispatcher
from minwii.musicxml import musicXml2Song
from minwii.config import SONG_FILE_PATH
from minwii.globals import PLAYING_MODES_DICT
from minwii.log import console, LOG_FORMAT_VERSION, envLogger


class MinWii(object):
    
    def __init__(self, wiimoteSupport=True, fullscreen=False) :
        envLogger.info('winwii log format version : %s', LOG_FORMAT_VERSION)
        self.wiimoteSupport = wiimoteSupport
        self.fullscreen = fullscreen
        LaunchScreen()
        self.app = Desktop()
        self.synth = Synth()
        self.screenResolution = (1024,768)
        envLogger.info('résolution écran : %s', self.screenResolution)
        self.nwiimotes = 0
        self.initWiimotes()
        self.firstSong = True
    
    def initWiimotes(self) :
        if self.wiimoteSupport :
            from pywiiuse import pygame_wiimouse
            from minwii.config import IR_POSITION
            pygame_wiimouse.init(4, 5, self.screenResolution, IR_POSITION) # look for 4, wait 5 seconds
            self.nwiimotes = nwiimotes = pygame_wiimouse.get_count()
            console.debug('wiimotes found : %d', nwiimotes)
            self.WT = WT = pygame_wiimouse.WT
            WT.pause()
        else :
            self.WT = _WTFacade()

    def run(self) :
        "séquençage de l'affichage des écrans"
        displayFlags = 0
        if self.fullscreen :
            displayFlags = displayFlags | pygame.FULLSCREEN
        pygame.display.set_mode(self.screenResolution, displayFlags)
        pygame.display.set_caption('MINWii')
        WT = self.WT
        
        songFile, playMode, wiimoteIndex = '', 'NORMAL', 0

        while True :

            exit, songFile, playMode, wiimoteIndex = \
                self.selectSongAndOptions(songFile, playMode, wiimoteIndex)
            if exit : break
            
            WT.selectWiimote(wiimoteIndex)
            WT.resume()

            instrumentDescription = self.selectInstrument()
            if not instrumentDescription :
                WT.pause()
                continue
            
            self.runPlayingScreen(songFile, playMode, instrumentDescription)
            
            WT.pause()
    
    
    def selectSongAndOptions(self, songFile, playMode, wiimoteIndex) :
        """ lance l'écran de paramétrage et retourne un tuple comportant :
            - drapeau de sortie de l'application (booléen)
            - chemin du fichier de la chanson
            - mode (entier)
            - wiimote sélectionnée (entier)
        """
        home = Home(songPath=SONG_FILE_PATH,
                    songFile=songFile,
                    playMode=playMode,
                    wiimoteIndex=wiimoteIndex,
                    nwiimotes=self.nwiimotes)
        app = self.app
        home.connect(QUIT, app.quit)
        app.run(home)
        app.close(home)
        
        #logging
        if home.exitApp :
            console.debug("sortie de l'application")
        else :
            actual_wiimotes = self.WT.get_count()
            if self.firstSong :
                self.firstSong = False
            else :
                envLogger.info('NEW_LOG_FILE')
            console.info('chanson : %s', home.songFile)
            console.info('mode : %s', home.modeSelect.value)
            if actual_wiimotes is None :
                console.info('HID : souris')
            elif actual_wiimotes == 0 :
                console.info('HID : souris (pas de wiimote trouvée)')
            else :
                console.info('HID : wiimote %d', home.selectedWiimote.value + 1)
        #---
        
        return (home.exitApp,
                home.songFile,
                home.selectedPlayMode,
                home.selectedWiimoteIndex)
    
    def selectInstrument(self) :
        """ lance l'écran de sélection de l'instrument et retourne
            un dictionnaire comportant la description de l'instrument
        """
        selector = InstrumentSelector()
        selector.run()
        selector.stop()
        pygame.event.clear()
        EventDispatcher.reset()
        instru = selector.selectedInstrument
        if instru :
            console.info('instrument : %s', instru['name'])
            console.info('preset : %d', instru['preset'])
            console.info('bank : %d', instru['bank'])
            console.info('ajustement octave : %d', instru['octave'])
        return instru
    
    def runPlayingScreen(self, songFile, playMode, instrumentDescription) :
        """ Lance l'écran de jeu principal avec la chanson 'songFile' dans le mode 'playMode'
            avec l'instrument midi 'instrumentDescription'.
        """
        playMode = PLAYING_MODES_DICT[playMode]
        song = musicXml2Song(songFile)
        bank, preset = instrumentDescription['bank'], instrumentDescription['preset']
        octave = instrumentDescription['octave']
        self.synth.adjust_octave(0, octave)
        self.synth.program_select(0, bank, preset)
        playingScreen = SongPlayingScreen(self.synth, song, mode=playMode)
        playingScreen.run()
        pygame.event.clear()
        EventDispatcher.reset()


class _WTFacade :
    """ Classe utilitaire pour singer l'api
        de pygame_wiimouse en cas d'abscence de wiimote.
    """
    selectWimoteIndex = 0
    def pause(self):
        pass
    def resume(self):
        pass
    def selectWiimote(self, i):
        pass
    def get_count(self) :
        return None
