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

import os
import re
import sys

not_changing_message = '''
به نظر می‌رسد که %s یک فایل زیرنویس نیست.
برای جلوگیری از نابودی فایل‌های غیر زیرنویس این فایل تغییر نخواهد کرد.
'''
class UiGtk:
    def __init__ (self):
        # args
        self.files = sys.argv[:]
        self.total = len(self.files) - 1

        self.skipped = False

        # if no file was selected
        if self.total == 0:
            exit()

        # load subtitle fixer
        self.subtitle_fixer = SubtitleFixer()

        # gtk
        try:
            from gi.repository import Gtk
            Gtk.Widget.set_default_direction(Gtk.TextDirection.RTL)
        except ImportError:
            import gtk as Gtk
            Gtk.widget_set_default_direction(Gtk.TEXT_DIR_RTL)

        self.Gtk = Gtk

        # create window
        self.setup_window()
        self.read_next_file()

        Gtk.main()

    def setup_window(self):
        Gtk = self.Gtk

        self.window = Gtk.Window()

        # setup main window
        self.window.resize(400, 400)
        self.window.set_border_width(5);
        self.window.set_icon_name('gtk-edit')
        self.window.connect('destroy', Gtk.main_quit)
        self.window.connect('delete_event', Gtk.main_quit)

        main_box = Gtk.VBox()
        main_box.set_spacing(5)
        self.window.add(main_box)

        # Result
        box = Gtk.HBox()
        label = Gtk.Label('نتیجه:')
        box.pack_start(label, False, False, 0)
        main_box.pack_start(box, False, False, 0)

        # Text View
        self.text_view = Gtk.TextView()
        self.text_view.set_editable(False)
        self.scrolled_window = Gtk.ScrolledWindow()
        self.scrolled_window.add(self.text_view)
        main_box.add(self.scrolled_window)

        # Progress Bar
        self.progress_bar = Gtk.ProgressBar()
        self.progress_bar.set_show_text(True)
        main_box.pack_start(self.progress_bar, False, False, 0)

        # apply/cancel/skip
        box = Gtk.HBox()
        box.set_spacing(5)
        main_box.pack_start(box, False, False, 0)

        self.apply_button = Gtk.Button(stock=Gtk.STOCK_APPLY)
        self.apply_button.connect('clicked', self.on_apply_clicked)
        box.pack_end(self.apply_button, False, False, 0)

        if len(self.files) > 2:
            self.skip_button = Gtk.Button('Skip')
            self.skip_button.connect('clicked', self.on_skip_clicked),
            box.pack_end(self.skip_button, False, False, 0)

        button = Gtk.Button(stock=Gtk.STOCK_CANCEL)
        button.connect('clicked', self.on_cancel_clicked),
        box.pack_end(button, False, False, 0)

        self.window.show_all()

    def read_next_file(self):
        # Remove previous from list
        self.files.remove(self.files[0])

        # if on last file exit
        if not len(self.files):
            exit()

        # update progress bar
        cur = self.total - len(self.files) + 1
        self.progress_bar.set_fraction(float(cur)/self.total)
        self.progress_bar.set_text('%d of %d' % (cur, self.total))

        # Update Window title
        self.window.set_title('SubtitleFixer (%s)' % self.files[0])

        if self.files[0][-4:] != '.srt':
            self.skipped = True
            lines = not_changing_message % self.files[0]
        else:
            self.skipped = False
            f = open(self.files[0], 'r')
            lines = f.read((2**10)**2)
            f.close()
            lines = self.subtitle_fixer.decode_string(lines)

        self.text_view.get_buffer().set_text(lines)

    def on_cancel_clicked(self, button):
        self.window.emit('delete_event', None)

    def on_skip_clicked(self, button):
        self.read_next_file()

    def on_apply_clicked(self, button):
        if self.skipped:
            self.read_next_file()
            return

        with open(self.files[0], 'r') as f:
            lines = f.read()

        lines = self.subtitle_fixer.decode_string(lines)

        os.remove(self.files[0])
        with open(self.files[0], 'w') as f:
            f.write(lines.encode('utf-8'))

        self.read_next_file()

class SubtitleFixer:
    def __init__(self):
        self.time = '\d\d:\d\d:\d\d,\d\d\d'
        self.number = u'۰۱۲۳۴۵۶۷۸۹'

        self.string = ''

    def fix_encoding(self):
        assert isinstance(self.string, str), repr(self.string)
        #if isinstance(self.string, unicode):
            #return 'utf8'

        try:
            self.string.decode('utf8', 'strict')
            self.string = self.string.decode('utf8')
            return 'utf8'
        except UnicodeError:
            pass

        try:
            self.string.decode('utf16', 'strict')
            self.string = self.string.decode('utf16')
            return 'utf16'
        except UnicodeError:
            pass

        self.string = self.string.decode('windows-1256')
        return 'windows-1256'

    def fix_italic(self):
        self.string = self.string.replace('<i>' , '')
        self.string = self.string.replace('</i>', '')

    def fix_arabic(self):
        self.string = self.string.replace(u'ي', u'ی')
        self.string = self.string.replace(u'ك', u'ک')

    def fix_question_mark(self):
        # quistion mark in persina is ؟ not ?
        self.string = self.string.replace('?', u'؟')

    def fix_other(self):
        self.string = self.string.replace(u'\u202B', u'')

        lines  = self.string.split('\n')
        string = ''

        for line in lines:
            if re.match('^%s\s-->\s%s$' % (self.time, self.time), line):
                string += line
            elif re.match('^%s\s-->\s%s$' % (self.time, self.time), line[:-1]):
                string += line
            elif line.strip() == '':
                string += line
            elif re.match('^\d+$', line):
                string += line
            elif re.match('^\d+$', line[:-1]):
                string += line
            else:
                # this should be subtitle
                s = re.match('^([\.!?]*)', line)

                try:
                    line = re.sub('^%s' % s.group(), '', line)
                except:
                    pass

                # use persian numbers
                for i in range(0, 10):
                    line = line.replace(str(i), self.number[i])

                # for ltr problems some peoples put '-' on EOL
                # it should be in start
                if len(line) != 0 and line[-1] == '-':
                    line = '- %s' % line[:-1]
                line += s.group()

                # put rtl char in start of line (it forces some player to show that line rtl
                string += u'\u202B' + unicode(line)

            # noting to see here
            string += '\n'

            self.string = string


    def decode_string(self, string):
        self.string = string

        self.fix_encoding()

        self.fix_italic()
        self.fix_arabic()
        self.fix_question_mark()
        self.fix_other()

        return self.string


if __name__ == '__main__':
    UiGtk()
