# -*- coding: utf-8 -*-

"""
    CMS

    Simple Content Management System
"""

module = request.controller
resourcename = request.function

if not settings.has_module(module):
    raise HTTP(404, body="Module disabled: %s" % module)

from datetime import timedelta

# =============================================================================
def index():
    """ Module homepage """

    return s3db.cms_index(module, alt_function="index_alt")

# -----------------------------------------------------------------------------
def index_alt():
    """
        Module homepage for non-Admin users when no CMS content found
    """

    # Just redirect to the list of Posts
    s3_redirect_default(URL(f="post"))

# -----------------------------------------------------------------------------
def series():
    """ RESTful CRUD controller """

    # Pre-process
    def prep(r):
        if r.component:
            # Settings are defined at the series level
            table = s3db.cms_post
            _avatar = table.avatar
            _avatar.readable = _avatar.writable = False
            _avatar.default = r.record.avatar
            _location = table.location_id
            if not r.record.location:
                _location.readable = _location.writable = False
            _replies = table.replies
            _replies.readable = _replies.writable = False
            _replies.default = r.record.replies
            _roles_permitted = table.roles_permitted
            _roles_permitted.readable = _roles_permitted.writable = False
            _roles_permitted.default = r.record.roles_permitted
            if r.record.richtext:
                table.body.represent = lambda body: XML(body)
                table.body.widget = s3_richtext_widget
            else:
                table.body.represent = lambda body: XML(s3_URLise(body))
                table.body.widget = None
            # Titles do show up
            table.name.comment = ""
        return True
    s3.prep = prep

    return s3_rest_controller(rheader=s3db.cms_rheader)

# -----------------------------------------------------------------------------
def tag():
    """ RESTful CRUD controller """

    return s3_rest_controller()

# -----------------------------------------------------------------------------
def blog():
    """
        RESTful CRUD controller for display of a series of posts as a full-page
        read-only showing last 5 items in reverse time order

        @ToDo: Convert to dataList
    """

    # Pre-process
    def prep(r):
        s3db.configure(r.tablename, listadd=False)
        return True
    s3.prep = prep

    # Post-process
    def postp(r, output):
        if r.record:
            response.view = s3base.S3CRUD._view(r, "cms/blog.html")
        return output
    s3.postp = postp

    output = s3_rest_controller("cms", "series")
    return output

# -----------------------------------------------------------------------------
def post():
    """ RESTful CRUD controller """

    tablename = "cms_post"
    # Filter out those posts which are part of a series
    #table = s3db[tablename]
    #s3.filter = (table.series_id == None)

    # Custom Method to add Comments
    s3db.set_method(module, resourcename,
                    method = "discuss",
                    action = discuss)

    def prep(r):
        if r.interactive:
            if r.method in ("create", "update"):
                table = r.table

                # Filter from a Profile page?"
                series = get_vars.get("~.series_id$name", None)
                if series:
                    # Lookup ID
                    stable = db.cms_series
                    row = db(stable.name == series).select(stable.id,
                                                           limitby=(0, 1)
                                                           ).first()
                    if row:
                        field = table.series_id
                        field.default = row.id
                        field.readable = field.writable = False

                # Context from a Profile page?"
                location_id = get_vars.get("(location)", None)
                if location_id:
                    field = table.location_id
                    field.default = location_id
                    field.readable = field.writable = False

                page = get_vars.get("page", None)
                url = get_vars.get("url") # custom redirect?
                if page:
                    table.name.default = page
                    table.name.readable = table.name.writable = False
                    _crud = s3.crud_strings[tablename]
                    _crud.label_create = T("New Page")
                    _crud.title_update = T("Edit Page")
                    if not url:
                        url = URL(c="default", f="index", vars={"page": page})
                    s3db.configure(tablename,
                                   create_next = url,
                                   update_next = url,
                                   )

                _module = get_vars.get("module", None)
                if _module:
                    table.avatar.readable = table.avatar.writable = False
                    table.location_id.readable = table.location_id.writable = False
                    table.date.readable = table.date.writable = False
                    table.expired.readable = table.expired.writable = False
                    # We always want the Rich Text widget here
                    table.body.widget = s3base.s3_richtext_widget
                    resource = get_vars.get("resource", None)
                    if resource in ("about", "contact", "help", "index"):

                        if resource == "about":
                            # We're creating/updating text for the About page
                            table.name.default = "About Page"
                        elif resource == "contact":
                            # We're creating/updating text for a Contact page
                            table.name.default = "Contact Page"
                        elif resource == "help":
                            # We're creating/updating text for the Help page
                            table.name.default = "Help Page"
                        else:
                            # We're creating/updating text for the Home page
                            table.name.default = "Home Page"

                        #table.title.readable = table.title.writable = False
                        table.replies.readable = table.replies.writable = False
                        if not url:
                            url = URL(c=_module, f=resource)
                    else:
                        record = get_vars.get("record", None)
                        if record:
                            # We're creating/updating text for a Profile page
                            table.name.default = "%s %s Profile Page" % (resource, record)
                            table.title.readable = table.title.writable = False
                            table.replies.readable = table.replies.writable = False
                            if not url:
                                url = URL(c=_module, f=resource, args=[record, "profile"])
                        elif resource:
                            # We're creating/updating text for a Resource Summary page
                            table.name.default = "%s Summary Page Header" % resource
                            table.title.readable = table.title.writable = False
                            table.replies.readable = table.replies.writable = False
                            if not url:
                                url = URL(c=_module, f=resource, args="summary")
                        else:
                            # We're creating/updating a Module home page
                            table.name.default = "%s Home Page" % _module
                            _crud = s3.crud_strings[tablename]
                            _crud.label_create = T("New Page")
                            _crud.title_update = T("Edit Page")
                            if not url:
                                url = URL(c=_module, f="index")

                    s3db.configure(tablename,
                                   create_next = url,
                                   update_next = url,
                                   )

                layer_id = get_vars.get("layer_id", None)
                if layer_id:
                    # Editing cms_post_layer
                    table.name.default = "Metadata Page for Layer %s" % layer_id
                    table.name.readable = table.name.writable = False
                    table.avatar.readable = table.avatar.writable = False
                    table.location_id.readable = table.location_id.writable = False
                    table.title.readable = table.title.writable = False
                    table.replies.readable = table.replies.writable = False
                    table.date.readable = table.date.writable = False
                    table.expired.readable = table.expired.writable = False
                    _crud = s3.crud_strings[tablename]
                    _crud.label_create = T("Add Metadata")
                    _crud.title_update = T("Edit Metadata")

                if r.component_name == "module":
                    modules = {}
                    _modules = current.deployment_settings.modules
                    for module in _modules:
                        if module in ("appadmin", "errors", "ocr"):
                            continue
                        modules[module] = _modules[module].name_nice
                    s3db.cms_post_module.field.requires = \
                        IS_IN_SET_LAZY(lambda: sort_dict_by_values(modules))

        return True
    s3.prep = prep

    output = s3_rest_controller(rheader=s3db.cms_rheader)
    return output

# -----------------------------------------------------------------------------
def page():
    """
        RESTful CRUD controller for display of a post as a full-page read-only
        - with optional Comments
    """

    found = True
    get_vars = request.get_vars
    if "name" in get_vars:
        table = s3db.cms_post
        query = (table.name == get_vars.name) & \
                (table.deleted != True)
        row = db(query).select(table.id, limitby=(0, 1)).first()
        if row:
            request.args.append(str(row.id))
        else:
            found = False

    # Pre-process
    def prep(r):
        if not found:
            r.error(404, T("Page not found"), next=auth.permission.homepage)
        s3db.configure(r.tablename, listadd=False)
        return True
    s3.prep = prep

    # Post-process
    def postp(r, output):
        if r.record and not r.transformable():
            output = {"item": s3base.S3XMLContents(r.record.body).xml()}
            current.menu.options = None
            response.view = s3base.S3CRUD._view(r, "cms/page.html")
            if r.record.replies:
                ckeditor = URL(c="static", f="ckeditor", args="ckeditor.js")
                s3.scripts.append(ckeditor)
                adapter = URL(c="static", f="ckeditor", args=["adapters",
                                                              "jquery.js"])
                s3.scripts.append(adapter)

                # Toolbar options: http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Toolbar
                js = "".join((
'''i18n.reply="''', str(T("Reply")), '''"
var img_path=S3.Ap.concat('/static/img/jCollapsible/')
var ck_config={toolbar:[['Bold','Italic','-','NumberedList','BulletedList','-','Link','Unlink','-','Smiley','-','Source','Maximize']],toolbarCanCollapse:false,removePlugins:'elementspath'}
function comment_reply(id){
 $('#cms_comment_post_id__row').hide()
 $('#cms_comment_post_id__row1').hide()
 $('#comment-title').html(i18n.reply)
 $('#cms_comment_body').ckeditorGet().destroy()
 $('#cms_comment_body').ckeditor(ck_config)
 $('#comment-form').insertAfter($('#comment-'+id))
 $('#cms_comment_parent').val(id)
 var post_id = $('#comment-'+id).attr('post_id')
 $('#cms_comment_post_id').val(post_id)
}'''))

                s3.js_global.append(js)
        return output
    s3.postp = postp

    output = s3_rest_controller("cms", "post")
    return output

# -----------------------------------------------------------------------------
def filter_formstyle(row_id, label, widget, comment, hidden=False):
    """
        Custom Formstyle for FilterForm

        @param row_id: HTML id for the row
        @param label: the label
        @param widget: the form widget
        @param comment: the comment
        @param hidden: whether the row should initially be hidden or not
    """

    if hidden:
        _class = "advanced hide"
    else:
        _class= ""

    if label:
        return DIV(label, widget, _id=row_id, _class=_class)
    else:
        return DIV(widget, _id=row_id, _class=_class)

# -----------------------------------------------------------------------------
def cms_post_age(row):
    """
        The age of the post
        - used for colour-coding markers of Alerts & Incidents
    """

    if hasattr(row, "cms_post"):
        row = row.cms_post
    try:
        date = row.date
    except:
        # not available
        return messages["NONE"]

    now = request.utcnow
    age = now - date
    if age < timedelta(days=2):
        return 1
    elif age < timedelta(days=7):
        return 2
    else:
        return 3

# -----------------------------------------------------------------------------
def newsfeed():
    """
        RESTful CRUD controller for display of posts as a filterable dataList
        (use with /datalist method)
    """

    # Load Model
    table = s3db.cms_post
    stable = db.cms_series
    title_list = T("Latest Information")

    # Hide Posts linked to Modules and Maps & Expired Posts
    s3.filter = (FS("post_module.module") == None) & \
                (FS("post_layer.layer_id") == None) & \
                (FS("expired") != True)

    # Ensure that filtered views translate into options which update the Widget
    if "~.series_id$name" in get_vars:
        series_name = get_vars["~.series_id$name"]
        # Disabled as can change filters dynamically
        # @ToDo: Better Mechanism: Another field in cms_series?
        #if series_name == "Request":
        #    title_list = T("Latest Requests")
        #elif series_name == "Offer":
        #    title_list = T("Latest Offers")
        series = db(stable.name == series_name).select(stable.id,
                                                       cache=s3db.cache,
                                                       limitby=(0, 1)).first()
        if series:
            series_id = str(series.id)
            get_vars.pop("~.series_id$name")
            get_vars["~.series_id__belongs"] = series_id

    s3.crud_strings["cms_post"].title_list = title_list

    contact_field = settings.get_cms_person()
    org_field = settings.get_cms_organisation()
    org_group_field = settings.get_cms_organisation_group()
    show_events = settings.get_cms_show_events()

    hidden = not settings.get_cms_filter_open()

    from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter, S3DateFilter
    filter_widgets = [S3TextFilter(["body"],
                                   label = T("Search"),
                                   _class = "filter-search",
                                   #_placeholder = T("Search").upper(),
                                   ),
                      S3LocationFilter("location_id",
                                       label = T("Filter by Location"),
                                       hidden = hidden,
                                       ),
                      ]
    fappend = filter_widgets.append
    finsert = filter_widgets.insert

    if show_events:
        fappend(S3OptionsFilter("event_post.event_id",
                                label = T("Filter by Disaster"),
                                hidden = hidden,
                                ))

    if org_field:
        fappend(S3OptionsFilter(org_field,
                                label = T("Filter by Organization"),
                                # Can't use this for created_by as integer, use field.represent instead
                                #represent = "%(name)s",
                                hidden = hidden,
                                ))

    if org_group_field:
        group_label = settings.get_org_groups()
        if group_label:
            fappend(S3OptionsFilter(org_group_field,
                                    label = T("Filter by %(type)s") % dict(type=T(group_label)),
                                    # Can't use this for created_by as integer, use field.represent instead
                                    #represent = "%(name)s",
                                    hidden = hidden,
                                    ))

    fappend(S3DateFilter("date",
                         label = T("Filter by Date"),
                         hide_time = True,
                         hidden = hidden,
                         ))

    if settings.get_cms_show_tags():
        finsert(1, S3OptionsFilter("tag_post.tag_id",
                                   label = T("Filter by Tag"),
                                   represent = "%(name)s",
                                   hidden = hidden,
                                   ))

    if settings.get_cms_bookmarks() and auth.user:
        finsert(1, S3OptionsFilter("bookmark.user_id",
                                   label = T("Filter by Bookmark"),
                                   # Can't just use "" as this is then omitted from rendering
                                   options = {"*": T("All"),
                                              auth.user.id: T("My Bookmarks"),
                                              },
                                   cols = 2,
                                   multiple = False,
                                   hidden = hidden,
                                   ))

    notify_fields = [(T("Date"), "date"),
                     (T("Location"), "location_id"),
                     ]

    len_series = db(stable.deleted == False).count()
    if len_series > 3:
        notify_fields.insert(0, (T("Type"), "series_id"))
        # Multiselect widget
        finsert(1, S3OptionsFilter("series_id",