#!/usr/bin/python
# -*- coding: utf-8 -*-
# -*- Mode: python; c-basic-offset: 4 -*-
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

"""
Simple note taking desktop app (Python Gtk3)
 
@author: Mario César Señoranis Ayala <mariocesar@creat1va.com>

@license: GPLv3

    Copyright (C) 2014 Mario César Señoranis Ayala <mariocesar@creat1va.com>
     
    This program or library is free software; you can redistribute it
    and/or modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 3 of the License, or (at your option) any later version.
     
    This library 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
    Lesser General Public License for more details.
     
    You should have received a copy of the GNU Lesser General
    Public License along with this library; if not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301 USA.
"""

import os
from gi.repository import Gtk, Gdk, Gio, GLib

css = """
#text_view, #note_window {
    background-color: #FFFFE0;
}

#text_view {
    font-family: Liberation Mono;
    font-size: 9px;
}

#text_view:selected,
#text_view:selected:focus {
    background-color: #FFD700;
    color: #000;
}
"""

class NoteWindow(Gtk.Window):
    def __init__(self, application):
        super(NoteWindow, self).__init__()
        self.application = application

        self.set_name('note_window')
        self.set_title('Note')
        self.set_resizable(True)
        self.set_keep_above(True)
        self.set_size_request(460, 500)
        self.set_border_width(10)
        self.set_gravity(Gdk.Gravity.SOUTH_EAST)
        self.set_type_hint(Gdk.WindowTypeHint.NORMAL)


        # Signals
        self.restore_position()
        self.connect('delete_event', self.save_position)

        # UI

        hb = Gtk.HeaderBar()
        hb.set_show_close_button(True)
        hb.props.title = "Note"
        self.set_titlebar(hb)

        self.grid = Gtk.Grid()
        self.grid.margin_left = 20
        self.grid.margin_right = 20
        self.grid.margin_top = 20
        self.grid.margin_bottom = 20

        self.add(self.grid)

        # Text View

        self.textview = Gtk.TextView()
        self.textview.set_name('text_view')
        self.textview.set_wrap_mode(Gtk.WrapMode.WORD)

        self.textbuffer = self.textview.get_buffer()
        self.textbuffer.connect("changed", self.on_text_buffer_change)

        self.checkout_text_buffer()

        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        scrolledwindow.add(self.textview)

        self.grid.attach(scrolledwindow, 0, 1, 3, 1)

    def checkout_text_buffer(self):
        if os.path.exists(self.application.notes_file_path):
            with file(self.application.notes_file_path, 'r+') as f:
                self.textbuffer.set_text(f.read())      
        else:
            file(self.application.notes_file_path, 'a').close()

    def commit_text_buffer(self):
        text = self.textbuffer.get_text(
            self.textbuffer.get_start_iter(),
            self.textbuffer.get_end_iter(),
            False)

        with file(self.application.notes_file_path, 'w+') as f:
            f.write(text)

    def restore_position(self):
        try:
            x, y = self.application.settings['window-position']
        except ValueError:
            self.set_position(Gtk.WindowPosition.CENTER)
        else:
            self.move(x, y)

    def save_position(self, widget, event):
        self.application.settings['window-position'] = widget.get_position()

    def on_text_buffer_change(self, widget):
        self.commit_text_buffer()


class Application(Gtk.Application):
    data_dir = os.path.join(GLib.get_user_data_dir(), 'notes')

    def do_activate(self):
        css_provider = Gtk.CssProvider()
        css_provider.load_from_data(css.encode('UTF-8'))
        screen = Gdk.Screen.get_default()

        self.settings = Gio.Settings("org.gnome.notes")
        self.notes_file_path = os.path.join(self.data_dir, 'notes.txt')

        if not os.path.exists(self.data_dir):
            os.makedirs(self.data_dir)

        self.window = NoteWindow(self)

        context = self.window.get_style_context()
        context.add_provider_for_screen(
            screen, css_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

        self.add_window(self.window)
        self.window.show_all()

    def do_startup(self):
        Gtk.Application.do_startup(self)

    def do_shutdown(self):
        Gtk.Application.do_shutdown(self)

    def on_quit(self, widget, data):
        self.quit()

if __name__ == '__main__':
    application = Application()
    application.run(None)