// This class encapsulates our signup review display behavior so that we
// can simply instantiate on the given page and it will implement all
// necessary behavior
//
// Christopher Dorman <cdorman@ironicdesign.com>

var Review = Class.create({

    // This function handles all clicks on the items, as well as all form actions for the items

    handle: function (e) {
        console.group ("handle()");

        var review = $('review');

        // A reference to the initiating element
        var el = Event.element (e);

        // If we're dealing with a form, we're submitting it.
        // If not, we're getting details for the item
        var f = el.form;
        console.log ("Form is %o", f);

        // If the click was inside a form, we handle the button that was clicked
        if (f) {

            // We're only handling buttons here
            if (el.tagName.toLowerCase() == 'input' && el.readAttribute ('type') == 'button') {

                // Don't propogate
                Event.stop (e);
             
                console.log ("Getting contextual information");

                // Get the action
                var action = f.readAttribute ('name');
             
                // Get the current id
                var current;
                if (action == "attend") {
                    current = el.up ('tr').previous ('tr').id;
                } else {
                    current = el.up ('tr').id.replace ('_' + action, '');
                }
                console.log ("current ID is %s", current);

                // Get our parameters
                var param = Form.serialize (f, true);
                //param = $H(param);

                // Disable the form
                Form.disable (f);
             
                // Call the routine to reclassify the address
                new Ajax.Request ('/review/' + action.toLowerCase(),
                                  { method: 'post',
                                    contentType: 'application/json',
                                    postBody: Object.toJSON(param),
                                    onFailure: function () {
                                        alert ('Could not ' + action.toLowerCase() + ' entry');
                                        Form.enable(f);
                                    },
                                    onSuccess: function (response) {
                                        console.log (action + " succeeded");
                                        if (response.responseText == 'SUCCESS') {
                                            console.log ("SUCCESS string returned");
                                            if (action == 'attend') {
                                                var type = el.up ('table').id.replace (/_review$/, '');
                                                // Remove the row and details from the list
                                                $(current).remove ();
                                                $(type + '_' + current + '_details').remove ();
                                            } else if (action == 'limit' || action == 'deactivate') {
                                                var type = el.up ('table', 1).id.replace (/_review$/, '');
                                                $(type + '_' + current + '_details').remove ();
                                                $(current).down ('td').fire('review:handle');
                                            } else {
                                                // Remove the row with the button we just acted on and enable the form
                                                $(current + '_' + action).remove ();
                                                Form.enable(f);
                                            }
                                        } else {
                                            Form.enable(f);
                                        }
                                    },
                                  });
            }
        } else {
            console.log ("Getting contextual information");
            var id = el.up ('tr').identify();
            var uid = el.up ('tr').down ('td').innerHTML;
            var type = el.up ('table').id.replace (/_review$/, '');
         
            var param = {uid: uid, type: type};
         
            console.log ("Checking for existing details for the object");
         
            var body = $(type + '_' + id + '_details');
         
            if (body) {
                if (body.visible()) {
                    body.hide();
                } else {
                    body.show();
                }
            } else {
                console.log ("Retrieving object details with params %o, json %s", param, Object.toJSON(param));
                new Ajax.Request ('/review/details',
                                  { method: 'post',
                                    contentType: 'application/json',
                                    postBody: Object.toJSON(param),
                                    evalJSON: true,
                                    sanitizeJSON: true,
                                    onFailure: function () {
                                        alert ("Couldn't display details");
                                    },
                                    onSuccess: function (response) {
                                        console.log ("Request success");
                                        var r = response.responseJSON;
                                        console.log ("Got response %o", r);
                                        r.id = id;
                                        r.type = type.escapeHTML();
                                        console.log ("Getting template");
                                        if (type == "address") {
                                            console.log ("Setting up address template");
                                            if (r.asvalid) {
                                                r.asvalid = r.asvalid.escapeHTML();
                                            } else {
                                                r.asvalid = "TRUE";
                                            }
                                            if (r.cn)
                                                r.cn = r.cn.escapeHTML();
                                            if (r.fmalternateemail) {
                                                r.fmalternateemail = r.fmalternateemail.escapeHTML();
                                            } else {
                                                r.fmalternateemail = "FALSE";
                                            }
                                            if (r.fmbirthmonth)
                                                r.fmbirthmonth = r.fmbirthmonth.escapeHTML();
                                            if (r.fmbirthyear)
                                                r.fmbirthyear = r.fmbirthyear.escapeHTML();
                                            if (r.fmexternal) {
                                                r.fmexternal = r.fmexternal.escapeHTML();
                                            } else {
                                                r.fmexternal = "FALSE";
                                            }
                                            if (r.fmgender)
                                                r.fmgender = r.fmgender.capitalize().escapeHTML();
                                            if (r.fmmaxrecipientsperemail)
                                                r.fmmaxrecipientsperemail = r.fmmaxrecipientsperemail.escapeHTML();
                                            if (r.fmmaxrecipientsper24hr)
                                                r.fmmaxrecipientsper24hr = r.fmmaxrecipientsper24hr.escapeHTML();
                                            if (r.fmoccupation)
                                                r.fmoccupation = r.fmoccupation.capitalize().escapeHTML();
                                            if (r.fmverifyanswer)
                                                r.fmverifyanswer = r.fmverifyanswer.escapeHTML();
                                            if (r.fmverifyquestion)
                                                r.fmverifyquestion = r.fmverifyquestion.capitalize().escapeHTML();
                                            if (r.ipcountry)
                                                r.ipcountry = r.ipcountry.escapeHTML();
                                            if (r.iphostnumber)
                                                r.iphostnumber = r.iphostnumber.escapeHTML();
                                            if (r.postalcode)
                                                r.postalcode = r.postalcode.escapeHTML();
                                            if (r.sn)
                                                r.sn = r.sn.escapeHTML();
                                            if (r.uid)
                                                r.uid = r.uid.escapeHTML();
                                        }
                                        if (type == "customer") {
                                            if (r.cn)
                                                r.cn = r.cn.escapeHTML();
                                            if (r.owner)
                                                r.owner = r.owner.escapeHTML();
                                        }
                                        if (type == "domain") {
                                        }
                                        if (type == "server") {
                                            if (r.idreviewcandidate)
                                                r.idreviewcandidate = r.idreviewcandidate.escapeHTML();
                                            if (r.idmemcachecandidate)
                                                r.idmemcachecandidate = r.idmemcachecandidate.escapeHTML();
                                        }
                                        console.log ("type is %s and id is %s and record values are %o", type, id, r);
                                        var template = review.retrieve (type);
                                        var display = template.evaluate (r);
                                        $(id).insert ( {after : display} );
                                        if (type == "address" && r.asvalid == "FALSE")
                                            $(id + '_deactivate').hide();
                                    }
                                  });
            }
            console.log ("Done with details");
        }

        console.groupEnd();
    },

    // This extracts some content from the page to be used as a
    // template, attaches bits of behavior to several items, then
    // kicks off an async request to load the data.

    initialize: function () {
        console.group ("initialize()");

        // Speed access
        var review = $('review');

        console.log ("Instantiating our templates and clearing out the source");
        review.store('server_list', new Template ($('server_review_list').innerHTML));
        $('server_review_list').update('');
        review.store('server', new Template ($('server_review_details').innerHTML));
        $('server_review_details').remove();
        review.store('customer_list', new Template ($('customer_review_list').innerHTML));
        $('customer_review_list').update('');
        review.store('customer', new Template ($('customer_review_details').innerHTML));
        $('customer_review_details').remove();
        review.store('domain_list', new Template ($('domain_review_list').innerHTML));
        $('domain_review_list').update('');
        review.store('domain', new Template ($('domain_review_details').innerHTML));
        $('domain_review_details').remove();
        review.store('address_list', new Template ($('address_review_list').innerHTML));
        $('address_review_list').update('');
        review.store('address', new Template ($('address_review_details').innerHTML));
        $('address_review_details').remove();

        console.log ("Setting observers");

        // We want to handle clicks on the buttons in the forms
        $('server_review', 'customer_review', 'domain_review', 'address_review').compact().invoke ('observe', 'click', this.handle.bindAsEventListener (this));

        // We need to be able to fire the handle routine when certain details are updated
        $('server_review', 'customer_review', 'domain_review', 'address_review').compact().invoke ('observe', 'review:handle', this.handle.bindAsEventListener (this));

        // We want to set up the lists to hold the data
        this.lists = {server: $A(), customer: $A(), domain: $A(), address: $A()};

        // Then, get the data
        new Ajax.Request ("/review/list",
                          { method: 'post',
                            contentType: 'application/json',
                            evalJSON: true,
                            sanitizeJSON: true,
                            onFailure: function () {
                                alert ("Failed to retrieve list");
                            },
                            onSuccess: this.loadData.bind (this)
                          });

        console.groupEnd();
    },

    loadData: function (response) {
        console.group ("loadData()");

        $A(response.responseText.evalJSON (true)).each (function (e) {
            // This allows us to sort quickly on IE and use canned binary search
            e.toString = function () { return this.uid.toLowerCase() };

            this.lists[e.type].push (e);
        }.bind (this));

        $H(this.lists).each (function (l) {
            l.value.sort();
        });

        this.renderLists ();

        console.groupEnd();
    },

    renderLists: function () {
        console.group ("renderLists()");

        var review = $('review');

        $H(this.lists).each (function (l) {

            console.log ("Rendering " + l.key + " list");
            var template = review.retrieve (l.key + '_list');
            var html = [];
            console.time ("Constructing array of rows");
            l.value.inject (html,
                            function (array, r) {
                                if (r.uid)
                                    r.uid = r.uid.escapeHTML();
                                if (r.reason)
                                    r.reason = r.reason.escapeHTML();
                                r.html = template.evaluate (r);
                                array.push (r.html);
                                return array;
                            });
            console.timeEnd ("Constructing array of rows");

            // Update the HTML for the table
            if (html.length > 0) {
                console.time ("Creating string");
                var output = html.join ('');
                console.timeEnd ("Creating string");
                console.time ("Display");
                $(l.key + '_review_list').update (output);
                console.timeEnd ("Display");
            } else {
                $(l.key + '_review').update ("No items of this type need attention at this time");
            }
        }.bind (this));

        console.groupEnd();
    }
});

