layerinfo "type" = "layout";
layerinfo "name" = "Sitescheme views";
layerinfo redist_uniq = "siteviews/layout";
layerinfo is_internal = "1";

class Siteviews {
    function builtin need_res(string res);
    function builtin start_capture();
    function builtin end_capture() : string;

    function builtin set_content(string area, string text);
}


property builtin Siteviews SITEVIEWS {
    noui = 1;
    doc_flags = "[sys]";
    des = "Instance of the Siteviews class";
}

function Page::print() {
    if ( $*SITEVIEWS ) {
        $*SITEVIEWS->start_capture();
        $this->print_head();
        $this->print_default_stylesheet();
        $this->print_theme_stylesheet();
        $*SITEVIEWS->set_content("head",$*SITEVIEWS->end_capture());
        $this->print_title();

        $this->print_body();
    } else {
       print safe "<b>This style is not intended for direct use.</b>";
    }
}

function Page::print_title() {
    # Do not actually *print* anything here, or in overridden instances, just call set_content with windowtitle or title as appropriate.
    $*SITEVIEWS->set_content("windowtitle",$this->view_title());
}

function Page::print_default_stylesheet() {
    # Do not actually *print* any stylesheets here, but you can $*SITEVIEWS->need_res(...); here to pull in anything.
    $*SITEVIEWS->need_res( "stc/siteviews/layout.css" );
}

function Page::print_theme_stylesheet() {}

# ItemRange

function ItemRange::print(string{} opts) {
    if ($.all_subitems_displayed) { return; }

    var string anchor = $opts{"anchor"} ? "#$opts{"anchor"}" : "";
    var string class = $opts{"class"} ? $opts{"class"} : "action-box";

    """<div class="$class">""";
    print """<p style="font-weight: bolder; margin: 0 0 .5em 0;">""" + lang_page_of_pages($.current, $.total) + "</p>";
    var string url_prev = $this->url_of($.current - 1);
    """<span class="page-prev">""";
    if ($.current != 1) {
        print " <b><a href='$url_prev$anchor'>$*comment_page_prev</a></b> ";
    } else {
        print " <b>$*comment_page_prev</b> ";
    }
    """</span>
    <span style="text-align: center" class="page-links">""";
    foreach var int i (1..$.total) {
        if ($i == $.current) { "<b>[$i]</b> "; }
        else {
            var string url_of = $this->url_of($i);
            "<a href='$url_of$anchor'><b>[$i]</b></a> ";
        }
        if ($i % 10 == 0){ """<br />"""; }
        }
    """</span>""";
    var string url_next = $this->url_of($.current + 1);
    """<span class="page-next">""";
    if ($.current != $.total) {
         print " <b><a href='$url_next$anchor'>$*comment_page_next</a></b> ";
    } else {
         print " <b>$*comment_page_next</b> ";
    }
    """</span>""";
    if ( $.url_all != "" ) {
        """<p><a href="$.url_all">View All</a></p>""";
    }

    "</div>";
}

# IconsPage

set text_icons_keyword_sep = ", ";
set text_icons_inactive = "[Inactive]";

function IconsPage::print_title() {
    # Do not actually *print* anything here, or in overridden instances, just call set_content with windowtitle or title as appropriate.
    $*SITEVIEWS->set_content("title",$this->view_title());
}

function IconsPage::print_default_stylesheet() {
    # Do not actually *print* any stylesheets here, but you can $*SITEVIEWS->need_res(...); here to pull in anything.
    $*SITEVIEWS->need_res( "stc/allpics.css" );
}

function IconsPage::print_body() {
    var int piccount = 0;
    if ( size($.icons) == 0 ) {
        """<h1>$*text_icons_page_empty_header</h1><p>""";
        if ( $.can_manage ) {
            "You don't have any icons uploaded. <a href=\"" + $.journal->icon_manage_url() + "\">Upload an icon here</a>.";
        } else {
            """$.journal hasn't uploaded any icons. You can <a href="$*SITEROOT/manage/subscriptions/user?journal=$.journal.username">be notified</a> when $.journal uploads an icon, if you want.""";
        }
    } else {
        """<h1>$*text_icons_page_header</h1><p>""";
        print "These are the icons for ";
        print $.journal;
        print ". ";
        if ( $.can_manage ) {
            "Would you like to <a href=\"" + $.journal->icon_manage_url() + "\">upload a new icon or edit your icon keywords, comments, and descriptions</a>?";
        } else {
            """We can <a href="$*SITEROOT/manage/tracking/user?journal=$.journal.username">notify</a> you when this account uploads a new one.""";
        }
        """</p>""";

        if ( $.pages.num_subitems_displayed > 6 ) {
            $.pages->print({ "anchor" => "" });
        }

        """<p>""";
        var int sort_ct = 0;
        foreach var string k ($.sort_keyseq) {
            var string text = lang_icon_sortorder_title($k);
            if ( $k == $.sortorder ) {
                print safe """$text""";
            } else {
                print safe """<a href='$.sort_urls{$k}'>$text</a>""";
            }
            if ( (++$sort_ct) < size $.sort_keyseq) { print $*text_default_separator; }
        }

        """<div class="icon-container">""";
        foreach var Icon i ($.icons) {
            $piccount++;

            if ($piccount % 2 == 1) {
                """<div class="icon-row">""";
            }

            $i->print();

            if ($piccount % 2 == 1) {

            } else {
                """</div>""";
            }
        }
        if ($piccount) {
            if ($piccount % 2 == 1) {
                """</div>""";
            }

        } else {
        }
        """</div>""";

        $.pages->print({ "anchor" => "" });
        """<div class="clear-floats"></div>""";
    }
}


# EntryPage Functions

set text_post_comment = "Post a new comment";
set text_comment_reply = "Reply to this";
set entry_date_format = "iso";
set text_comment_from = "";
set text_comment_date = "";
set text_comment_ipaddr = "";
set text_comment_link = "Thread";
set text_frozen = "(frozen comment)";
set text_tags = "Entry tags:";
set text_multiform_check = "Select";
set entry_time_format = "short_24";
set comment_time_format = "short_24";


function EntryPage::print_default_stylesheet() {
    # Do not actually *print* any stylesheets here, but you can $*SITEVIEWS->need_res(...); here to pull in anything.
    $*SITEVIEWS->need_res( "stc/entrypage.css" );

}

function ReplyPage::print_default_stylesheet() {
    # Do not actually *print* any stylesheets here, but you can $*SITEVIEWS->need_res(...); here to pull in anything.
    $*SITEVIEWS->need_res( "stc/replypage.css" );

}


function Page::print_entry(Entry e)
"The meat of each new layout. Describes how each page will look. In nearly all cases, the logic and decision-making processes should come from pre-existing functions in core2, and should not get written here. If you limit the structure of the page to HTML, function calls, and attached CSS, then you will be able to pick up all of the enhancements  and accessibility requirements managed by core2."
{
    ## For most styles, this will be overridden by FriendsPage::print_entry and such.
    $e->print_wrapper_start();
    """<div class="header">\n""";
    """<div class="inner">\n""";
    $e->print_userpic();
    """<div class="poster-info">\n""";
    $e->print_poster();
    var string timefmt = $this.timeformat24 ? "short_24" : "short";
    $e->print_time( $*entry_date_format, $timefmt );
    """</div>\n""";
    """</div>\n""";
    """<div class="action-box">\n""";
    """<div class="inner">\n""";
    $e->print_management_links();
    """</div>\n""";
    """</div>\n""";
    """</div>\n""";
    """<div class="currents">\n""";
    $e->print_metadata();
    $e->print_tags();
    """</div>\n""";
    """<div>\n""";
    """<div class="contents usercontent">\n""";
    """<div class="inner">\n""";
    $e->print_metatypes();
    $e->print_subject();
    $e->print_text();
    """</div>\n""";
    """</div>\n""";
    """</div>\n""";

    """<div class="footer">\n""";
    """<div class="inner">\n""";
    $this->print_entry_footer($e);
    "</div>\n</div>\n";

    $e->print_wrapper_end();

}


function Entry::print_poster {
    var Page p = get_page();
    var string emptyclass = ((($p isa RecentPage and not $p isa FriendsPage) or $p isa MonthPage or $p isa DayPage) and $p.journal.journal_type != "C") ? "empty" : "";
    print safe "<span class=\"poster entry-poster $emptyclass\">";
    if ($p isa FriendsPage or $p isa EntryPage or $p isa ReplyPage) {
        print safe "$this.poster.name ("; $this.poster->print();""") wrote""";
        if (not $this.poster->equals($this.journal)) {
            print safe " in ";
            $this.journal->print();
        }
    }
    else {
        if (not $this.poster->equals($this.journal)) {
          $this.poster->print();
        }
    }
    print safe "</span>";
}

function Comment::print_poster() {
    var Page p = get_page();
    var string poster = defined $this.poster ? $this.poster->as_string() : "<span class=\"anonymous\">$*text_poster_anonymous</span>";
    if ($this.metadata{"imported_from"}) {
        $poster = "<span class=\"imported-from\">$poster ($*text_openid_from " + $this.metadata{"imported_from"} + ")</span>";
    }
    if ($p isa ReplyPage) {
        if (defined $this.poster) {
            print safe "<span class=\"poster comment-poster\">$*text_comment_from $this.poster.name ($poster) wrote</span>"; }
        else {
            print safe "Someone wrote";
        }
        if (not $this.poster->equals($this.journal)) {
            print safe " in ";
            $this.journal->print();
        }
        if ( $this.admin_post ) {
            """<span>(""";
            $this->print_admin_post_icon();
            print safe $*text_admin_post_note;
            """)</span>""";
        }
    } else {
        print safe "<span class=\"poster comment-poster\">$*text_comment_from $poster";
        if ( $this.admin_post ) {
            """<span>(""";
            $this->print_admin_post_icon();
            print safe $*text_admin_post_note;
            """)</span>""";
        }
        print "</span>\n";
    }
}
function EntryPage::print_entry_footer(Entry e) {
    """<hr class="above-entry-interaction-links" />
    <div class="comment-pages-wrapper">""";
    $.comment_pages->print({ "anchor" => "comments", "class" => "comment-pages toppages comment-page-list" });
    """</div>""";
    $e->print_interaction_links("topcomment");
}

function EntryPage::print_comment_section(Entry e) {
   "<div id='comments'><div class='inner'>";
   if ( $e.comments.comments_disabled_maintainer ) {
        """<div class='comments-message'>$*text_comments_disabled_maintainer</div>""";
   }
   $.comment_nav->print({ "class" => "comment-pages toppages" });
   $this->print_reply_container({ "target" => "topcomment" });

   if ($.comment_pages.total_subitems > 0) {
      $this->print_multiform_start();
   }

   $this->print_comments($.comments);
   if ($.comment_pages.total_subitems > 0) {
        "<div class='bottomcomment'>";
        """<hr class="below-entry-interaction-links" />""";
        $e->print_interaction_links("bottomcomment");
        "</div>";
   }
   if ($.comment_pages.total_subitems > 0) {
        $.comment_nav->print({ "class" => "comment-pages bottompages" });
        $this->print_reply_container({ "target" => "bottomcomment" });
        $this->print_multiform_actionline();
        $this->print_multiform_end();
   }
    """<div class="commment-pages-wrapper">""";
   $.comment_pages->print({ "anchor" => "comments", "class" => "comment-pages bottompages comment-page-list" });
    "</div></div></div>";
}

function EntryPage::print_comments (Comment[] cs) {
    if (size $cs == 0) { return; }

    # Iterate over the comment tree structure
    var Comment c;
    var Comment[] cs_stack = reverse $cs;
    while (size $cs_stack) {
        $c = pop $cs_stack;
        push $cs_stack, reverse $c.replies;

        var string parity = $c.depth % 2 ? "odd" : "even";
        var int indent = ($c.depth - 1) * 25;
        "<div class='comment-thread comment-depth-$parity comment-depth-$c.depth'>\n";
        "<div id='$c.dom_id' class='dwexpcomment' style='margin-left: ${indent}px; margin-top: 5px;";
        if ($c.hidden_child) {
            " display: none;";
        }
        "'>\n";
        if ($c.full) {
            $this->print_comment($c);
        } else {
            $this->print_comment_partial($c);
        }
        "</div></div>";
    }
}

function EntryPage::print_comment (Comment c) {
# ReplyPage and EntryPage work nicest if they output the same structure for printing comments and entries, but this requires to manually change both ReplyPage::print_comment and EntryPage::print_entry.  Layout authors can also choose to override separately for different structures.

    $c->print_wrapper_start();
    """<div class="header">\n""";
    """<div class="inner">\n""";
    $c->print_userpic();
    """<div class="comment-info">\n""";
    $c->print_subject({ "format" => "text" });
    $c->print_metatypes();
    $c->print_poster();
    var string timefmt = $this.timeformat24 ? "short_24" : "short";
    $c->print_time( $*entry_date_format, $timefmt );
    $c->print_metadata();

   print safe """<span class="commentpermalink">(<a href="$c.permalink_url">link</a>)</span>\n"""; $c->print_management_links();
    if ($this.multiform_on) {
            """<span class="multiform-checkbox">""";
            $c->print_multiform_check();
            print safe " <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label> ";
        "</span>";
        }
     if ( $c.comment_posted ) {
         print safe "<div class='comment-posted'>$*text_comment_posted</div>";
     }
    """</div>\n""";
    """</div>\n""";
    """</div>\n""";
    """<div class="contents usercontent">\n""";
    """<div class="inner">\n""";
    $c->print_text();
    """</div>\n""";
    """</div>\n""";
    """<div class="footer">\n""";
    """<div class="inner">\n""";
        $c->print_interaction_links();
    $c->print_reply_container();
    "</div>\n</div>\n";
    $c->print_wrapper_end();
}
function ReplyPage::print_comment (Comment c) {
# ReplyPage and EntryPage work nicest if they output the same structure for printing comments and entries, but this requires to manually change both ReplyPage::print_comment and EntryPage::print_entry.  Layout authors can also choose to override separately for different structures.

    ## For most styles, this will be overridden by FriendsPage::print_entry and such.
    $c->print_wrapper_start();
    """<div class="header">\n""";
    """<div class="inner">\n""";
    $c->print_userpic();
    """<div class="poster-info">\n""";
    $c->print_poster();
    $c->print_metatypes();
    var string timefmt = $this.timeformat24 ? "short_24" : "short";
    $c->print_time( $*entry_date_format, $timefmt );
    """</div>\n""";
    """</div>\n""";
    """</div>\n""";
    """<div>\n""";
    """<div class="contents usercontent">\n""";
    """<div class="inner">\n""";
    $c->print_subject();
    $c->print_text();
    """</div>\n""";
    """</div>\n""";
    """</div>\n""";
    """<div class="footer">\n""";
    """<div class="inner">\n""";
        $c->print_interaction_links();
    $c->print_reply_container();
    "</div>\n</div>\n";

    $c->print_wrapper_end();

}

function ReplyPage::print_body
{
    if (not $.entry.comments.enabled) {
        print safe "<h2>$*text_reply_nocomments_header</h2><p>$*text_reply_nocomments</p>";
        return;
    }

    if ($.replyto isa Entry) {
        var Entry e = $.replyto as Entry;
        $this->print_entry($e);
    }
    elseif ($.replyto isa Comment) {
        var Comment c = $.replyto as Comment;
        $this->print_comment($c);
    }
    """<hr style="margin: 1em 0;">""";
    """<div class="readlink"> (""";
    $.entry.comments->print_readlink();
    ") </div>\n";
    """<h1>Post a comment in response:</h1>""";
    $.form->print();
}

function EntryPage::print_title() {
    # Do not actually *print* anything here, or in overridden instances, just call set_content with windowtitle or title as appropriate.
    $*SITEVIEWS->set_content("windowtitle",$this.journal.username + $*text_default_separator + $this->view_title());
}

function ReplyPage::print_title() {
    # Do not actually *print* anything here, or in overridden instances, just call set_content with windowtitle or title as appropriate.
    $*SITEVIEWS->set_content("windowtitle",$this.journal.username + $*text_default_separator + $this->view_title());
}

# MonthPage Functions

function MonthPage::print_title() {
    # Do not actually *print* anything here, or in overridden instances, just call set_content with windowtitle or title as appropriate.
    $*SITEVIEWS->set_content("windowtitle",$this.journal.username + $*text_default_separator + $this->view_title());
}

function MonthPage::print_body {
var MonthDay[] days = $*reverse_sortorder_month ? reverse $.days : $.days;
    """
    <div id="archive-month">
        <div class="inner">
    """;
    $this->print_navigation( { "class" => "highlight-box" } );

    """
            <div class="month">
                <div class="inner">
                    <dl>
                    """;

    foreach var MonthDay d ($days) {
        if ($d.has_entries) {
            """<dt><a href="$d.url"><b>""";
                    print lang_ordinal($d.day);
            "</b></a></dt>";

            "\n<dd>";
            $d->print_subjectlist();
            "</dd>\n";
        }
    }
                """
                </dl>
            </div><!-- month>inner -->
        </div><!-- month -->

        </div><!-- archive-month>inner -->
    </div><!--archive-month -->
    """;
}

function MonthDay::print_subjectlist() {
var Entry[] entries = $*reverse_sortorder_month ? reverse $.entries : $.entries;
    # Too many tables...
    var Page p = get_page();

    foreach var Entry e ($entries) {
        $e->print_time("none", "");
        $e->print_poster();
        $e->print_subject();
        $e->print_metatypes();
        if ($e.comments.count > 0) {
            print safe " - " + get_plural_phrase($e.comments.count, "text_read_comments");
        }
        if ($e.comments.screened) {
            print safe " <b>$*text_month_screened_comments</b>";
        }
        "<br />\n";
        $e->print_tags();
        "<br />\n";
    }
}