#!/usr/local/bin/python2.7
# -*- coding: utf-8 -*-

#import psyco
#psyco.full()
import sys, os

from optparse import OptionParser

def check_libs():
    """Check for required libs.

    If some not found, show/print a message.
    Exit if requirements aren't met."""
    _libs = [('mutagen', '(usually python-mutagen or just mutagen)',
            'http://code.google.com/p/mutagen/'),
         ('configobj', '(usually python-configobj)',
            'http://code.google.com/p/configobj/'),
         ('pyparsing', '(python-pyparsing or python-parsing in most distros)',
            'http://pyparsing.wikispaces.com/'),
         ('PyQt4', '(python-qt4 usually)',
            'http://www.riverbankcomputing.co.uk/software/pyqt/intro')]

    found = True
    errors = []
    msg = "Error: The %s module wasn't found. Please check that it's installed " \
            "properly. Download it from your distro's repository" \
            " %s or directly from %s \n"
    for lib in _libs:
        try:
            __import__(lib[0])
        except ImportError:
            print msg % lib
            errors.append(msg % lib)
            found = False

    msg = "Error: %s module wasn't found. %s. Please check that it's " \
        "installed properly. You can download it from your distro's " \
        "repository (%s), or download directly from %s.\n"

    try:
        if not found:
            from PyQt4.QtGui import QApplication, QMessageBox
            app = QApplication([])
            QMessageBox.critical(None, 'puddletag', '\n'.join(errors))
    except:
        pass
    
    if not found:
        sys.exit(1)

def create_log():
    """Creates a log file. Redirects sys.stderr sys.stdout output to it."""
    join = os.path.join
    rename = os.rename
    exists = os.path.exists

    from puddlestuff.constants import SAVEDIR
    if not os.path.exists(SAVEDIR):
        os.mkdir(SAVEDIR)

    for i in reversed(range(1, 5)):
        filename = join(SAVEDIR, 'log%d.log' % i)
        if exists(filename):
            rename(filename, join(SAVEDIR, 'log%d.log' % (i + 1)))

    log_file = join(SAVEDIR, 'log.log')
    if exists(log_file):
        rename(log_file, join(SAVEDIR, 'log1.log'))

    f = open(log_file, 'w')
    sys.stdout = StdOut(sys.stdout.write, f.write)
    sys.stderr = StdOut(sys.stderr.write, f.write)

def init(options, qapp):
    """Initializes things that need to be initialized.

    Parses command line options. Loads Translations. Sets fontsize."""

    if options.version:
        #It's already printed.
        exit()

    #create_log()
    if options.debug:        
        logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    load_language(qapp, options.langfile)

    if options.fontsize:
        try:
            size = int(options.fontsize)
            font = qapp.font()
            font.setPointSize(size)
            app.setFont(font)
        except IndexError:
            print 'No fontsize specified.'
        except ValueError:
            print 'Invalid fontsize specified.'

def load_language(qapp, langfile=None):
    """Loads the language file to be used by puddletag.

    app => QApplication object.
    langfile => If None, then the last option the user chose will be used.
                Should be a path to a Qt translation file (.qm)."""
    TRANSDIR = puddlestuff.constants.TRANSDIR

    global translators #Needs to live throughout app.
    translators = []

    if langfile:
        if not langfile.endswith('.qm'):
            print translate('Defaults', 'Invalid translation file.')
            langargs = None
        else:
            langargs = os.path.basename(langfile), os.path.dirname(langfile)
    else:
        langargs = None

    if not langargs:
        cparser = PuddleConfig()
        lang = cparser.get('main', 'lang', u'auto')
        langs = get_languages([TRANSDIR])

        if lang != 'auto':
            if lang in langs:
                f = langs[lang]
                langargs = os.path.basename(f), os.path.dirname(f)

        if not langargs and lang != 'default':
            locale = unicode(QLocale.system().name())
            if locale in langs:
                f = langs[locale]
                langargs = os.path.basename(f), os.path.dirname(f)

    if langargs and langargs != 'default':
        translator = QTranslator()
        translator.load("qt_" + QLocale.system().name(),
             QLibraryInfo.location(QLibraryInfo.TranslationsPath))
        translators.append(translator)

        if 'puddletag_' in langargs[0]:
            translator = QTranslator()
            locale = langargs[0][len('puddletag_'):-len('.qm')]
            translator.load("qt_" + locale,
                QLibraryInfo.location(QLibraryInfo.TranslationsPath))
            print "Locale: " + locale
            translators.append(translator)

        translator = QTranslator()
        if translator.load(*langargs):
            translators.append(translator)

    elif langargs != 'default':
        translator = QTranslator()
        translator.load("qt_" + QLocale.system().name(),
             QLibraryInfo.location(QLibraryInfo.TranslationsPath))
        print "Locale: " + unicode(QLocale.system().name())
        translators.append(translator)

    else:
        print "Loading default (ie. no) translation."

    for t in reversed(translators):
        qapp.installTranslator(t)
    puddlestuff.constants.trans_strings()
    puddlestuff.puddleobjects.trans_imagetypes()

def parse_cmd_options():
    usage = "Usage: %prog [options] [directory path]"
    parser = OptionParser(usage=usage)
    
    parser.add_option("--langfile", dest="langfile",
        default='',
        help="Path to a translation (.qm) file.", metavar="LANGFILE")
    parser.add_option("--fontsize", type='float',
        dest="fontsize", help="Default fontsize to use (in points).")
    parser.add_option("-d", "--debug", action="store_true",
        dest="debug", default=False, help="Show (useless) debug messages.")
    parser.add_option("-v", "--version", action="store_true",
        dest="version", default=False, help="Show version info and exit.")

    return parser.parse_args()

def print_info():
    """Print program info."""
    from puddlestuff import version_string, changeset
    if changeset:
        print translate('Defaults', 'puddletag Version: %1, Changeset: %2').arg(
            version_string).arg(changeset)
    else:
        print translate('Defaults', 'puddletag Version: %s' % version_string)

class StdOut(object):
    """Class to redirect stdout/in/err."""
    def __init__(self, old_write, new_write):
        """old_write should be the original sys.stdout.out
        new_write is a function is what sys.stdout.out will be replaced with.

        Text will be passed to both functions."""
        self._old_write = old_write
        self._new_write = new_write

    def write(self, text):

        self._old_write(text)
        try:
            self._new_write(text)
        except:
            pass


if __name__ == '__main__':
    check_libs()

    from PyQt4.QtGui import QApplication, QPixmap, QSplashScreen, QIcon
    from PyQt4.QtCore import (pyqtRemoveInputHook, QTranslator,
        QLibraryInfo, QLocale)
    import pdb, logging
    pyqtRemoveInputHook()

    #Load puddletag modules.
    from puddlestuff import resource #Needs to be first as other modules use it.
    import puddlestuff.constants
    from puddlestuff.puddleobjects import get_languages, PuddleConfig
    from puddlestuff.translations import translate

    #Init.
    print_info()
    app = QApplication(sys.argv)
    options, filenames = parse_cmd_options()
    init(options, app)

    #Depends on init being called first.
    from puddlestuff.puddletag import MainWin
    from puddlestuff.puddlesettings import load_gen_settings

    app.setWindowIcon(QIcon(":/appicon.png"))
    pixmap = QPixmap(':/puddlelogo.png')
    app.setOrganizationName("Puddle Inc.")
    app.setApplicationName("puddletag")

    splash = QSplashScreen(pixmap)
    splash.show()
    app.processEvents()
    win = MainWin()
    splash.close()
    win.setVisible(True)
    app.processEvents()

    #Check if dirnames passed on command line.
    if filenames:
        dirname = filenames[0]
        if dirname and os.path.exists(dirname):
            win.openDir(dirname, False)
    elif load_gen_settings([('&Load last folder at startup', False)])[0][1]:
        if win._lastdir and os.path.exists(win._lastdir[0]):
            win.openDir(win._lastdir[0], False)
    app.exec_()