# GNU Solfege - eartraining for GNOME
# Copyright (C) 2000, 2001, 2002  Tom Cato Amundsen
#
# This program is 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import gtk, gnome
import gu, widgets
import abstract, const, mpd
import statistics, statisticsviewer
import lessonfile
import string
from i18n import _


class Teacher(abstract.LessonbasedTeacher):
    OK = 0
    ERR_PICKY = 1
    ERR_NO_LESSONFILE = 2
    def __init__(self, exname,  app, use=const.USE_ID_BY_NAME):
        abstract.LessonbasedTeacher.__init__(self, exname, app, use)
        self.lessonfileclass = lessonfile.IdByNameLessonfile
        self.parse_lessonfile()

        self.m_statistics = statistics.LessonStatistics(self)
    def give_up(self):
        self.q_status = const.QSTATUS_GIVE_UP
    def new_question(self):
        if self.m_timeout_handle:
            gtk.timeout_remove(self.m_timeout_handle)
            self.m_timeout_handle = None
 
        if self.get_bool('config/picky_on_new_question') \
                 and self.q_status in [const.QSTATUS_NEW, const.QSTATUS_WRONG]:
             return Teacher.ERR_PICKY

        self.q_status = const.QSTATUS_NO

        if self.m_P:
            self.m_P.select_random_question()
            self.q_status = const.QSTATUS_NEW
            return self.OK
        else:
            return self.ERR_NO_LESSONFILE
    def guess_answer(self, answer):
        """
        Return: 1 if correct, None if wrong
        """        
        if answer == self.m_P.get_untranslated_name():
            if self.q_status == const.QSTATUS_NEW:
                self.m_statistics.add_correct(answer)
            self.maybe_auto_new_question()
            self.q_status = const.QSTATUS_SOLVED
            return 1
        else:
            if self.q_status == const.QSTATUS_NEW:
                self.m_statistics.add_wrong(self.m_P.get_untranslated_name(),
                                            answer)
                self.q_status = const.QSTATUS_WRONG
        

class Gui(abstract.LessonbasedGui):
    def __init__(self, teacher, window):
        abstract.LessonbasedGui.__init__(self, teacher, window)
        self.m_key_bindings = {'new_ak': self.new_question,
                               'repeat_ak': self.m_t.play_question,
                               'give_up_ak': self.give_up,
                               'show_ak': self.show_answer}
        ################
        # practise_box #
        ################
        self.g_bb = widgets.QuestionNameButtonTable()
        self.practise_box.pack_start(self.g_bb, gtk.FALSE)
        
        self.g_flashbar = gu.FlashBar()
        self.g_flashbar.show()
        self.practise_box.pack_start(self.g_flashbar, gtk.FALSE)
        self.practise_box.set_spacing(gnome.uiconsts.PAD)

        self.g_new = gu.bButton(self.action_area, _("New"), self.new_question)
        self.g_repeat = gu.bButton(self.action_area, _("Repeat"),
                                   lambda _o, self=self: self.m_t.play_question())
        self.g_give_up = gu.bButton(self.action_area, _("Give up"), self.give_up)
        self.g_give_up.set_sensitive(gtk.FALSE)

        self.g_show = gu.bButton(self.action_area, _("Show"), self.show_answer)
        self.g_show.set_sensitive(gtk.FALSE)
        self.practise_box.show_all()
        ##############
        # config_box #
        ##############
        self.config_box.set_spacing(gnome.uiconsts.PAD_SMALL)
        self.g_lessonfile_selector = widgets.SelectLessonfileWidget(
            self.m_t, self.g_win, self.update_gui_after_lessonfile_change)
        self.g_lessonfile_selector.show()
        self.config_box.pack_start(self.g_lessonfile_selector)
        # ------------------------------------------
        self._add_auto_new_question_gui(self.config_box)
        # ----------------------------------------------
        ##############
        # statistics #
        ##############
        self.setup_statisticsviewer(statisticsviewer.StatisticsViewer,
                                   _("Identify by name"))

        self.update_gui_after_lessonfile_change()
    def show_answer(self, widget=None):
        if self.m_t.q_status in (const.QSTATUS_SOLVED, const.QSTATUS_GIVE_UP):
            self.g_win.display_in_musicviewer(self.m_t.m_P.get_music())
    def update_answer_buttons(self):
        if self.m_t.m_P:
            self.g_bb.initialize(self.m_t.m_P.header.fillnum,
                                 self.m_t.m_P.header.filldir)
            for k in self.m_t.m_P.m_names_in_file_order:
                self.g_bb.add(k, self.m_t.m_P.m_names[k],
                      self.m_t.m_statistics.get_label_style(), self.on_click)
        else:
            self.g_bb.initialize(0, 0)
    def update_gui_after_lessonfile_change(self):
        if self.m_t.m_P:
            self.g_new.set_sensitive(gtk.TRUE)
        else:
            self.g_new.set_sensitive(gtk.FALSE)
        self.g_repeat.set_sensitive(gtk.FALSE)
        self.g_show.set_sensitive(gtk.FALSE)
        self.g_give_up.set_sensitive(gtk.FALSE)
        self.update_answer_buttons()
        self.g_win.set_title("Solfege - " + self.get_pretty_name())
    def give_up(self, _o=None):
        if self.m_t.q_status == const.QSTATUS_WRONG:
            self.g_flashbar.push(_("The answer is: %s") % self.m_t.m_P.get_name())
            self.m_t.give_up()
            self.g_show.set_sensitive(gtk.TRUE)
            self.g_new.set_sensitive(gtk.TRUE)
            self.g_give_up.set_sensitive(gtk.FALSE)
    def on_click(self, button):
        if self.m_t.q_status == const.QSTATUS_NO:
            self.g_flashbar.flash(_("Click 'New' to begin."))
            return
        if self.m_t.q_status == const.QSTATUS_SOLVED:
            if self.m_t.guess_answer(button.get_data('pcode')):
                self.g_flashbar.flash(_("Correct, but you have already solved this question"))
            else:
                self.g_flashbar.flash(_("Wrong, but you have already solved this question"))
        elif self.m_t.q_status in (const.QSTATUS_NEW, const.QSTATUS_WRONG):
            if self.m_t.guess_answer(button.get_data('pcode')):
                self.g_flashbar.flash(_("Correct"))
                self.g_new.set_sensitive(gtk.TRUE)
                self.g_show.set_sensitive(gtk.TRUE)
                self.g_give_up.set_sensitive(gtk.FALSE)
            else:
                self.g_flashbar.flash(_("Wrong"))
                if self.get_bool("config/auto_repeat_question_if_wrong_answer"):
                    self.m_t.play_question()
                self.g_give_up.set_sensitive(gtk.TRUE)
    def new_question(self, widget=None):
        g = self.m_t.new_question()
        if g == self.m_t.OK:
            self.g_repeat.set_sensitive(gtk.TRUE)
            self.g_new.set_sensitive(
                not self.get_bool('config/picky_on_new_question'))
            self.g_give_up.set_sensitive(gtk.FALSE)
            self.g_show.set_sensitive(gtk.FALSE)
            self.g_flashbar.clear()
            self.m_t.play_question()
    def on_start_practise(self):
        self.m_t.m_statistics.reset_session()
        gtk.timeout_add(const.SHORT_WAIT, lambda self=self:
            self.g_flashbar.flash(_("Click 'New' to begin.")))
    def on_end_practise(self):
        self.g_repeat.set_sensitive(gtk.FALSE)
        self.g_show.set_sensitive(gtk.FALSE)
        self.g_new.set_sensitive(gtk.TRUE)
        self.g_give_up.set_sensitive(gtk.FALSE)
        self.g_flashbar.clear()
        self.m_t.end_practise()
