# GNU Solfege - free ear training software
# vim: set fileencoding=utf-8 :
# Copyright (C) 2006, 2007, 2008 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 3 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, see <http://www.gnu.org/licenses/>.

# Lesson file related GUI code.

import warnings

import gtk
import locale
import lessonfile
import gu
import mpd

class ResolveLessonIdCrashDlg(gtk.Dialog):
    def __init__(self, lessonfile_manager, lesson_id):
        gtk.Dialog.__init__(self, _("Resolve lesson_id crash"), None,
            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                     gtk.STOCK_OK, gtk.RESPONSE_OK))
        vbox = gtk.VBox()
        vbox.set_border_width(12)
        self.vbox.pack_start(vbox)
        msg1 = gtk.Label("<b>%s</b>" % gu.escape(_("Lesson_id crash")))
        msg1.set_alignment(0.0, 0.5)
        msg1.set_use_markup(True)
        vbox.pack_start(msg1, False)
        msg2 = gtk.Label(_("The lesson_id has to be unique for each lesson file. Please select which lesson file shall keep the current lesson_id. The preselected file is Solfege's educated guess. Press 'Cancel' to postpone the decision."))
        msg2.set_alignment(0.0, 0.5)
        msg2.set_line_wrap(True)
        vbox.pack_start(msg2)
        self.radio_dict = {}
        for info in lessonfile_manager.get_lesson_file_info(lesson_id):
            if self.radio_dict.keys():
                g = self.radio_dict[self.radio_dict.keys()[0]]
            else:
                g = None
            ss = "%s %s" % (info['filename'], info['timestr'])
            if not isinstance(ss, unicode):
                ss = ss.decode(locale.getpreferredencoding(), 'replace')
            radiobutton = gtk.RadioButton(g, ss)
            radiobutton.show()
            radiobutton.set_data('filename', info['filename'])
            self.radio_dict[info['mtime']] = radiobutton
            vbox.pack_start(radiobutton)
        self.radio_dict[min(self.radio_dict.keys())].set_active(True)
        self.show_all()


def handle_lesson_id_crash(lessonfile_manager):
    for lesson_id in lessonfile_manager.iterate_duplicated_lesson_id():
        dlg = ResolveLessonIdCrashDlg(lessonfile_manager, lesson_id)
        ret = dlg.run()
        if ret == gtk.RESPONSE_OK:
            for b in dlg.radio_dict.values():
                # Create a new lesson_id and parse them into m_uiddb
                if not b.get_active():
                    f = lessonfile.LessonIdParser(b.get_data('filename'))
                    f.new_lesson_id()
                    lessonfile_manager.parse_into_uiddb(b.get_data('filename'))
                # and remove the duplicate entries from the entry we
                # want to keep.
                else:
                    lessonfile_manager.delete_not_fn(lesson_id, b.get_data('filename'))
        elif ret == gtk.RESPONSE_CANCEL:
            lessonfile_manager.ignore_duplicates_with_lesson_id(lesson_id)
        dlg.destroy()


def rn_markup(s):
    v = []
    for p1, p2, p3, sep in lessonfile.rnc_markup_tokenizer(s):
        v.append('<span font_family="serif"><span size="xx-large">%s</span><span size="small">%s</span><span size="x-large">%s%s</span></span>' % (p1, p2, p3, sep))
    return "".join(v)

def chordname_markup(s):
    v = []
    for nn, mod, sup, bass in lessonfile.chordname_markup_tokenizer(s):
        if bass:
            bass = u"/%s" % mpd.MusicalPitch.new_from_notename(bass).get_user_notename()
        nn = mpd.MusicalPitch.new_from_notename(nn).get_user_notename()
        nn = nn[0].upper() + nn[1:]
        v.append('%s%s<span size="large" rise="11000">%s</span>%s' % (nn, mod, sup, bass))
    return u'<span font_family="serif" size="xx-large">%s</span>' % u" ".join(v)

def new_labelobject(label):
    """
    label is a tuple (labeltype, labelstring) or a unicode string
    Return a gtk widget of some sort that displays the label.
    FIXME:
        If we in the future want some labels, for example chordlabel,
        to be transposable, then new_labelobject should return objects
        that are derived from gtk.Label, and they should have a
        a is_transposable method. Then Gui.on_new must call
        QuestionNameButtonTable and make it transpose the labels.
        But I don't think translated labels should have high priority.
    """
    if isinstance(label, basestring):
        # We hope all strings are unicode, but check for basestring just
        # in case some modules are wrong.
        l = gtk.Label(label)
        l.show()
    else:
        if isinstance(label, tuple):
            # I think only old code
            # that has  been removed. But let us keep the code until
            # we have a chanse to review.
            warnings.warn("lessonfilegui.new_labelobject: label is a tuple.",
                          DeprecationWarning)
            labeltype, labeldata = label
        else:
            labeltype = label.m_labeltype
            labeldata = label.m_labeldata
        if labeltype == 'progressionlabel':
            l = gu.HarmonicProgressionLabel(labeldata)
            l.show_all()
        else:
            l = gtk.Label()
            if labeltype == 'rnc':
                l.set_markup(rn_markup(labeldata))
            elif labeltype == 'chordname':
                l.set_markup(chordname_markup(labeldata))
            elif labeltype == 'plabel':
                l.set_markup("""<span font_family="serif"><span size="xx-large">%s</span><span size="small">%s</span><span size="x-large">%s</span></span>""" % labeldata)

            elif labeltype == 'pangomarkup':
                l.set_markup(labeldata)
            l.show()
    return l


