/* appjet:version 0.1 */

import("storage");
import("lib-datestrings");
import("lib-dispatch");

// Database
if (! storage.posts) { storage.posts = new StorableCollection(); }
if (! storage.seed) { storage.seed = Math.floor(Math.random() * 1e9); }

// favicon.ico
page.setTitle("JGate Change Log");

import("lib-start");
import("lib-admin");

// For adding/editing a ChangeLog entry.
function ChangeLogInputForm(prop)
{
   import("quickforms");

   var form = new QuickForm({action: "/clmod", method: "post"});
   form.addHeading("h", (prop && prop.id ? "Edit CL" : "Add a new CL"));
   form.addInputTextArea("summary", {label: "Summary", cols: 60, rows: 3,
                                     value: (prop ? prop.summary : undefined)});
   form.addInputTextArea("diff", {label: "Changes", cols: 60, rows: 30,
                                  value: (prop ? prop.diff : undefined)});
   if (prop && prop.id) {
       form.addInputHidden("modid", prop.id);
   }
   form.addSubmit("submit", "Submit");
   return form;
}

// Object for displaying a changelog entry.
function ChangeLogDisplay(obj, f)
{
   var n = (typeof(f) == 'function' ? f(obj) : obj);
   this.toHTML = function()
   {
       return supplant(n, """
<div class="postunit">
<div class="date"><a href="/change?id={id}">{date}</a></div>
<div class="post"><h2>{summary}</h2>
<div class="postBody">{diff}</div></div>
<div class="edit">{edit}</div>
</div>""");
   }
}

// Takes a StorableObject and converts it to the format the ChangeLogDisplay expects
function CLConverter(obj)
{
   var ret = {
       id: obj.id,
       date: (new Date(obj.date)).toLocaleDateString(),
       diff: obj.diff,
       summary: obj.summary
   };
   if (isAdmin()) {
       ret.edit = toHTML(A({href: "/edit?id="+obj.id }, "edit"));
   } else {
       ret.edit = ""
   }
   return ret;
}

// Page display
function printHeading()
{
   print(html((appjet._native.codeSection('header')[0].code)));
}

function printFirstN(n) {
   page.head.write(toHTML(LINK({rel: "alternate", title: "JGate ChangeLog Atom Feed",
                                href: "http://changelog.jgate.de/feed",
                                type: "application/atom+xml"})));
   printHeading();
   var dateSorted = storage.posts.sortBy("-date")
   dateSorted.limit(n).forEach(function(obj) {
       print(new ChangeLogDisplay(obj, CLConverter));
   });
   // print rest condensed
   dateSorted.skip(n).forEach(function(obj) {
       print(DIV({className: 'cl'},
                 A({href: "/change?id="+obj.id, className: 'cllink'},
                   "Earlier change on "+obj.date.toLocaleDateString()+
                   " at "+obj.date.toLocaleTimeString())));
   });
   if (isAdmin()) {
       print(ChangeLogInputForm());
   }
}

// Index
function get_main() {
   printFirstN(10);
}

function get_all() {
   printFirstN(10000);
}

function post_clmod() {
   if(! isAdmin())
       response.redirect("/");
   if (request.params.modid) {
       var o = getStorable(request.params.modid);
       o.summary = request.params.summary;
       o.diff = request.params.diff;
   } else {
       storage.posts.add({date: new Date(), summary: request.params.summary,
                          diff: request.params.diff});
   }
   response.redirect("/");
}

function get_edit()
{
   printHeading();
   storage.posts.sortBy("-date").forEach(function(obj) {
       if (obj.id == request.params.id) {
           print(new ChangeLogInputForm(CLConverter(obj)));
       } else {
           print(new ChangeLogDisplay(obj, CLConverter));
       }
   });
}

function get_change() {
   printHeading();
   var o = getStorable(request.params.id);
   if (! o)
       response.notFound();
   print(new ChangeLogDisplay(o, CLConverter));
}

function get_atom() {

   import("lib-atom");

   var entries = {
       base: storage.posts.sortBy("-date"),
       i: 0,
       forEach: function(f) {
           this.base.forEach(function(n) {
               return f({
                   author: "JGate",
                   title: n.summary,
                   link: "http://changelog.jgate.de/change?id="+n.id,
                   id: "tag:changelog.jgate.de,2009:obj/"+n.id,
                   updated: n.date,
                   summary: n.summary,
                   content: n.diff
           })})}
       }
   page.setMode("plain");
   response.setHeader("Content-Type", "application/atom+xml");
   print(raw(getMainFeed("JGate ChangeLog",
                             "/atom",
                             "tag:changelog.jgate.de,2009:/1",
                             storage.posts.sortBy("-date").first().date, entries)));

}

function get_feed() {
   response.redirect("http://changelog.jgate.de/atom");
}

function get_summary() {
   var max = 3;
   storage.posts.sortBy("-date").forEach(function(obj) {
       if (obj.summary) {
           print(B(A({href: "/change?id="+obj.id, target: "_top"},
                          shortMon[obj.date.getMonth()], " ", obj.date.getDate(), " ", obj.date.getFullYear()),
                     ": "), raw(obj.summary));
       }
       if (max-- <= 0) return false;
   });
   response.stop(true);
}

// atom feed requires raw output
if (request.path == "/atom")
{
    get_atom();
}
else
{
   if ((! storage.adminpassword) && request.path != "/start")
   {
       response.redirect("/start");
   }
   else
   {
       dispatch();
   }
}

/* appjet:header */
   <div id="bodyContent">
   <a href="http://jgate.de"> <img id="logo" src="http://static.jgate.de/img/logo-small.png" /></a>
   <div class="header">
       <h1><a href="http://changelog.jgate.de">
           JGate Change Log</a>
       </h1>
   </div>
   <div class="subhead">
       Recent changes on the JGate platform
   </div>

   <div class="sidebar">
   <p>JGate Change Log
   </p>
   <p>This change log keeps you updated with the recent changes on the JGate platform.</p>
   <img src="http://static.jgate.de/icon_label_feed_sm.gif" />&nbsp;&nbsp;<a href="feed">Subscribe to Changelog</a>
   </div>

/* appjet:css */
*{margin:0;padding:0;}
body{background-color:white;font-family:Arial,Helvetica,sans-serif;}
div{display:block;}
img{border:0 none;}
a{text-decoration:none;color:#075FB2;}
p{padding-top:12px;padding-bottom:12px;}
h1{font-family:'Lucida Grande','Trebuchet MS','Lucida Sans Unicode','Lucida Sans Regular',Verdana,sans-serif;font-weight:bold;letter-spacing:-1px;font-size:3.2em;line-height:1em;}
h2{margin:16px 0px 15px;font-size:22px;letter-spacing:-1px;}
h3{display:none;}
ul{margin:18px;}

/* Custom Styles */
img#logo{margin-left:155px;-webkit-border-bottom-left-radius:5px 5px;-webkit-border-bottom-right-radius:5px 5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;}
#bodyContent{margin-bottom:0px;margin-left:auto;margin-right:auto;margin-top:0px;text-align:left;width:900px;font-size:62.5%;}
div.header{margin-bottom:0px;margin-left:155px;margin-top:40px;width:500px;}
div.header,div.header a{color:#999;}
div.header a:hover{color:#CCCCCC;}
div.subhead{color:#999;font-size:1.4em;margin-bottom:30px;margin-left:155px;margin-top:10px;width:500px;}
div.postunit{clear:left;margin-bottom:35px;overflow:hidden;position:relative;width:700px;}
div.date{color:#C6C1A5;float:left;font-size:1.4em;padding-top:26px;text-align:right;width:130px;}
div.date a{color:#C6C1A5;font-size:14px;}
div.post{float:left;margin-left:25px;padding-bottom:10px;padding-top:5px;width:500px;}
div.postBody{font-size:14px;line-height:1.8em;margin-bottom:20px;color:#333;}
div.sidebar{color:#999;float:right;font-size:1.2em;margin-top:20px;width:175px;}
form.quickform,div#appjetfooter,a.cllink{margin:8px;}