# GutenPy - bookmarks.py
# Copyright (C) 2006 Lee Bigelow <ligelowbee@yahoo.com> 
# 
# 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 os, gtk, pango
from widgets import EntryDialog 

def delete_bookmark_cb(widget, udata=None):
    if udata: tv = udata
    else: tv = widget
    model, iter = tv.get_selection().get_selected()
    if not iter: return False
    model.remove(iter)
    return True

def add_bookmark(parent, page, auto_save=False):
    nb = parent.notebook
    if not page >= 0:
        page = nb.get_current_page()
    if not page >= 0: return

    textview = nb.get_nth_page(page).get_child()
    bm_treestore = parent.bookmarks
    textbuffer = textview.get_buffer()

    iter, top = textview.get_line_at_y(textview.get_visible_rect().y)
    line = iter.get_line()
    fname = textview.filename
    if auto_save:
        bname = fname
    else:
        bname = get_bookmark_name(parent, fname)
    if not bname: return None

    if bname == 'default': bname = fname
    textbuffer.create_mark(bname, iter, False)

    #find the top level iter for file
    diter = bm_treestore.get_iter_first()
    while diter:
        bm_fname = bm_treestore.get_value(diter,1)
        if fname == bm_fname:
            break
        diter = bm_treestore.iter_next(diter)

    #if it didn't exist create one
    if not diter:
        diter = bm_treestore.prepend(None, [fname, fname, 0,
                                            textview.charset])
    #set default mark if requested
    if fname == bname:
        bm_treestore.set(diter, 2, line, 3, textview.charset)
    #or look for named mark and set it
    else:
        niter = bm_treestore.iter_children(diter)
        while niter:
            bm_name = bm_treestore.get_value(niter, 1)
            if bname == bm_name: break
            niter = bm_treestore.iter_next(niter)
        if niter:
            bm_treestore.set(niter, 2, line)
        else:
            bm_treestore.prepend(diter, [fname, bname, line])

def goto_bookmark(parent, bm_treeview=None, textview=None, bname=None):
    if bm_treeview:
        bm_model, bm_iter = bm_treeview.get_selection().get_selected()
        if bm_iter:
            bfile, bname = bm_model.get(bm_iter, 0, 1)
        else: return
        textview = parent.find_textview_containing(bfile)
    if not textview: return
    textview.grab_focus()
    textbuffer = textview.get_buffer()
    textmark = textbuffer.get_mark(bname)
    if textmark:
        textview.scroll_to_mark(textmark, 0, True, 0.0, 0.0)


def get_bookmark_name(parent, fname):
    dialog = EntryDialog(parent, "Bookmark Name",
                         "Adding a bookmark for the file:\n"
                         "%s\n"
                         "Please enter a name for the bookmark:" %
                         os.path.basename(fname))
    dialog.set_default_response(gtk.RESPONSE_OK)
    dialog.entry.set_text('default')
    response = dialog.run()
    if response == gtk.RESPONSE_OK:
        bname = dialog.entry.get_text()
    else:
        bname = None
    dialog.destroy()
    return bname


class BookmarkTreeview(gtk.TreeView):
    def __init__(self, model=None):
        gtk.TreeView.__init__(self, model)
        self.expand_all()

        tvcolumn = gtk.TreeViewColumn()
        tvcolumn.set_title('Name')

        cell_renderer = gtk.CellRendererPixbuf()
        tvcolumn.pack_start(cell_renderer, False)
        tvcolumn.set_cell_data_func(cell_renderer, self.col_icon)

        cell_renderer = gtk.CellRendererText()
        tvcolumn.pack_start(cell_renderer, True)
        tvcolumn.set_cell_data_func(cell_renderer, self.col_name)

        tvcolumn.set_resizable(True)
        tvcolumn.set_expand(True)
        self.append_column(tvcolumn)
        textcell = gtk.CellRendererText()
        tvcolumn = gtk.TreeViewColumn('Line', textcell, text=2)
        self.append_column(tvcolumn)

    def col_icon(self, column, cell, model, iter):
        fname, bname = model.get(iter, 0, 1)
        if fname == bname:
            cell.set_property("stock-id", 'bookmark')
        else:
            cell.set_property("stock-id", None)

    def col_name(self, column, cell, model, iter):
        fname, bname = model.get(iter, 0, 1)
        if fname == bname:
            cell.set_property("text", bname)
        else:
            cell.set_property("text", "- %s" % bname)
        cell.set_property('ellipsize', pango.ELLIPSIZE_START)


class BookmarkDialog(gtk.Dialog):
    def __init__(self, parent):
        gtk.Dialog.__init__(self, 'Bookmarks', parent,
                            gtk.DIALOG_DESTROY_WITH_PARENT,
                            (gtk.STOCK_OK, gtk.RESPONSE_OK,
                             gtk.STOCK_DELETE, gtk.RESPONSE_REJECT,
                             gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
        self.set_default_response(gtk.RESPONSE_OK)
        self.parent_app = parent
        model = parent.bookmarks
        self.treeview = BookmarkTreeview(model)
        self.treeview.connect("row_activated", self.bookmark_activated)

        scrollw = gtk.ScrolledWindow()
        scrollw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrollw.add(self.treeview)
        self.vbox.pack_start(scrollw, True, True, 0)
        self.set_default_size(400,300)
        self.vbox.show_all()

    def bookmark_activated(self, treeview, path=None, column=None):
        self.emit('response', gtk.RESPONSE_OK)
        
