from quixote import get_request, get_response, get_session, redirect
from quixote.directory import Directory, AccessControlled
from quixote.html import TemplateIO, htmltext

import wcs
import wcs.admin.root
from wcs.backoffice.menu import *

from qommon import errors
from qommon.form import *

from links import Link


class LinkDirectory(Directory):
    _q_exports = ['', 'edit', 'delete']

    def __init__(self, link):
        self.link = link

    def _q_index(self):
        form = Form(enctype='multipart/form-data')
        form.add_submit('edit', _('Edit'))
        form.add_submit('delete', _('Delete'))
        form.add_submit('back', _('Back'))

        if form.get_submit() == 'edit':
            return redirect('edit')
        if form.get_submit() == 'delete':
            return redirect('delete')
        if form.get_submit() == 'back':
            return redirect('..')

        html_top('links', title = _('Link: %s') % self.link.title)
        r = TemplateIO(html=True)
        r += htmltext('<h2>%s</h2>') % _('Link: %s') % self.link.title
        r += htmltext('<p>')
        r += self.link.url
        r += htmltext('</p>')

        r += form.render()
        return r.getvalue()

    def edit(self):
        form = self.form()
        if form.get_submit() == 'cancel':
            return redirect('.')

        if form.is_submitted() and not form.has_errors():
            self.submit(form)
            return redirect('..')

        html_top('links', title = _('Edit Link: %s') % self.link.title)
        r = TemplateIO(html=True)
        r += htmltext('<h2>%s</h2>') % _('Edit Link: %s') % self.link.title
        r += form.render()
        return r.getvalue()


    def form(self):
        form = Form(enctype='multipart/form-data')
        form.add(StringWidget, 'title', title = _('Title'), required = True,
                value = self.link.title)
        form.add(StringWidget, 'url', title = _('URL'), required=False,
                value = self.link.url,
                hint=_('Leave empty to create a title'))
        form.add_submit('submit', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        return form

    def submit(self, form):
        for k in ('title', 'url'):
            widget = form.get_widget(k)
            if widget:
                setattr(self.link, k, widget.parse())
        self.link.store()

    def delete(self):
        form = Form(enctype='multipart/form-data')
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
                        'You are about to irrevocably delete this link.')))
        form.add_submit('submit', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        if form.get_submit() == 'cancel':
            return redirect('..')
        if not form.is_submitted() or form.has_errors():
            get_response().breadcrumb.append(('delete', _('Delete')))
            html_top('links', title = _('Delete Link'))
            r = TemplateIO(html=True)
            r += htmltext('<h2>%s</h2>') % _('Deleting Link: %s') % self.link.title
            r += form.render()
            return r.getvalue()
        else:
            self.link.remove_self()
            return redirect('..')


class LinksDirectory(AccessControlled, Directory):
    _q_exports = ['', 'new', 'listing', 'update_order']
    label = N_('Links')

    def _q_access(self):
        user = get_request().user
        if not user:
            raise errors.AccessUnauthorizedError()
        admin_role = get_cfg('aq-permissions', {}).get('links', None)
        if not (user.is_admin or admin_role in (user.roles or [])):
            raise errors.AccessForbiddenError(
                    public_msg = _('You are not allowed to access Links Management'),
                    location_hint = 'backoffice')

        get_response().breadcrumb.append(('links/', _('Links')))


    def _q_index(self):
        html_top('links', _('Links'))
        r = TemplateIO(html=True)
        get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'biglist.js'])

        r += htmltext('<ul id="main-actions">')
        r += htmltext('  <li><a class="new-item" href="new">%s</a></li>') % _('New Link')
        r += htmltext('</ul>')

        links = Link.select()
        Link.sort_by_position(links)

        r += htmltext('<ul class="biglist sortable" id="links-list">')
        for l in links:
            link_id = l.id
            r += htmltext('<li class="biglistitem" id="itemId_%s">') % link_id
            r += htmltext('<strong class="label"><a href="%s/">%s</a></strong>') % (link_id, l.title)
            r += htmltext('<p class="details">')
            r += l.url
            r += htmltext('</p>')
            r += htmltext('<p class="commands">')
            r += command_icon('%s/edit' % link_id, 'edit')
            r += command_icon('%s/delete' % link_id, 'remove')
            r += htmltext('</p></li>')
        r += htmltext('</ul>')
        return r.getvalue()

    def update_order(self):
        request = get_request()
        new_order = request.form['order'].strip(';').split(';')
        links = Link.select()
        dict = {}
        for l in links:
            dict[str(l.id)] = l
        for i, o in enumerate(new_order):
            dict[o].position = i + 1
            dict[o].store()
        return 'ok'


    def new(self):
        link_ui = LinkDirectory(Link())

        form = link_ui.form()
        if form.get_submit() == 'cancel':
            return redirect('.')

        if form.is_submitted() and not form.has_errors():
            link_ui.submit(form)
            return redirect('%s/' % link_ui.link.id)

        get_response().breadcrumb.append(('new', _('New Link')))
        html_top('links', title = _('New Link'))
        r = TemplateIO(html=True)
        r += htmltext('<h2>%s</h2>') % _('New Link')
        r += form.render()
        return r.getvalue()

    def _q_lookup(self, component):
        try:
            link = Link.get(component)
        except KeyError:
            raise errors.TraversalError()
        get_response().breadcrumb.append((str(link.id), link.title))
        return LinkDirectory(link)

    def listing(self):
        return redirect('.')

