//-------------------------------------------------------------------------------------

//	JibberBook v2.1

//	(c) 2008 Chris Jaure

//	license: MIT License

//	website: http://www.jibberbook.com/

//

//	inc/jbscript.js

//-------------------------------------------------------------------------------------



Element.extend({

    injectHTML: function(content, where){

        new Element('div').setHTML(content).getChildren().inject(this, where);

        return this;

    }

});



var Guestbook = {



    // object variables

    obj: {},

    fx: {},

    mouseDown: false,

    offset: 2,

    

    /*

     Function: submitForm

     

     Captures form submission event and uses ajaxReq instead.

     It also sets the form value _ajax to true, enabling the server-side script to differentiate regular submissions from ajax submissions.

    */

    submitForm: function(event){

        this.loading();

        this.obj.form.elements['_ajax'].value = true;

        this.ajaxReq.send(this.obj.form.getProperty('action'), this.obj.form.toQueryString());

        event.stop();

    },

    

    /*

     Function: processAddResponse

     

     Attached to onComplete event of ajaxReq. Expects JSON object to be returned from the server with 'value', 'content', and 'message' properties.

     

     value:

     1 indicates successful addition of comment

     2 indicates comment flagged as spam

     >=3 indicates validation error

     content: contains comment html if value == 1

     message: contains descriptive text associated with response

    */

    processAddResponse: function(){

        var response = Json.evaluate.attempt(this.ajaxReq.response.text);

        if (response) {

            if (response.value != '1') {

                this.showMessage(response.message, 'error');

                if (response.value == '2') 

                    this.obj.form.reset();

            }

            else {

                this.obj.commentWrapper.injectHTML(response.content, 'top');

                var new_comment = this.obj.commentWrapper.getFirst();

                if (this.obj.scroller == window) {

                    this.fx.scroll.toElement(this.obj.commentWrapper).chain(function(){

                        this.showMessage(response.message, 'confirm');

                    }.bind(this));

                }

                else {

                    this.fx.scroll.toTop();

                    this.showMessage(response.message, 'confirm');

                }

                this.obj.form.reset();

            }

        }

        else 

            this.showMessage(this.text.SERVER_ERROR, 'error');

        this.loaded();

    },

    

    /*

     Function: processLoadComments

     

     Attached to onComplete event of loadComments. Expects JSON object to be returned from the server with 'value' and 'content' properties.

     

     value:

     0 indicates no additional comments to load

     content: contains comment html

    */

    processLoadComments: function(){

        var response = Json.evaluate(this.loadComments.response.text);

        if (response.value == '0') {

            this.obj.scroller.removeEvents();

            this.obj.loadingMessage.setText(this.text.COMMENTS_LOADED);

        }

        this.obj.loadingMessage.injectHTML(response.content, 'before');

    },

    

    /*

     Function: loading

     

     Used to indicate ajax activity.

    */

    loading: function(){

        this.obj.submitButton.setProperties({

            'disabled': true,

            'value': this.text.LOADING

        });

    },

    

    /*

     Function: loaded

     

     Reverses actions of loading().

    */

    loaded: function(){

        this.obj.submitButton.setProperties({

            'disabled': false,

            'value': this.obj.submitButton.orgVal

        });

    },

    

    /*

     Function: show

     

     Attached to obj.scroller scroll event. Determines when to load additional comments.

    */

    show: function(){

        if (!this.mouseDown) {

            var dimensions = this.obj.scroller.getSize();

            var offset = (this.obj.scroller == window) ? 0 : this.obj.scroller.getTop();

            if (this.obj.loadingMessage.getTop() - offset < dimensions.scroll.y + dimensions.size.y) {

                if (!this.loadComments.running) {

                    this.loadComments.send('actions/loadcomments.php', 'offset=' + this.offset);

                    this.offset++;

                }

            }

        }

    },

    

    /*

     Function: showMessage

     

     Shows a message based on text and type.

     

     Parameters:

     text - Message text to show.

     type - Class to be applied to message container (overwrites all previous classes).

     

    */

    showMessage: function(text, type){

        this.obj.messageWrapper.setStyles({

            'left': (window.getWidth() / 2 - 150),

            'top': window.getScrollTop() + 30,

            'opacity': 0

        });

        this.obj.messageWrapper.className = type;

        this.obj.messageWrapper.getFirst().setText(text);

        this.fx.message.start(0.9);

    },

    

    /*

     Function: initialize

     

     This method must be called to start the script and enable ajax functionality.

     

     Parameters:

     form - id of the form

     comments - id of comments wrapper

     message - id of the message wrapper

    */

    initialize: function(form, comments, message, loading, text){

    

        // set objects

        this.obj.form = $(form);

        this.obj.commentWrapper = $(comments);

        this.obj.comments = this.obj.commentWrapper.getChildren();

        this.obj.messageWrapper = $(message);

        this.obj.submitButton = this.obj.form.getElement('input[type=submit]');

        this.obj.submitButton.orgVal = this.obj.submitButton.value;

        this.obj.loadingMessage = $(loading);

        this.text = text;

        var parent = this.obj.commentWrapper;

        while (parent) {

            if (parent.getTag() == 'body') {

                this.obj.scroller = window;

                parent = null;

                break;

            }

            var overflow = parent.getStyle('overflow');

            if (overflow == 'auto' || overflow == 'scroll') {

                this.obj.scroller = parent;

                parent = null;

            }

            else {

                parent = parent.getParent();

            }

        }

        

        // set effects

        this.fx.message = new Fx.Style(this.obj.messageWrapper, 'opacity');

        this.fx.scroll = new Fx.Scroll(this.obj.scroller, {

            'duration': 1000,

            'transition': Fx.Transitions.Circ.easeInOut

        });

        

        // set hxr objects 

        this.loadComments = new XHR({

            method: 'get',

            'onSuccess': this.processLoadComments.bind(this)

        });

        this.ajaxReq = new XHR({

            method: 'post',

            'onSuccess': this.processAddResponse.bind(this),

            'onFailure': function(){

                this.showMessage(this.text.ERROR, 'error');

                this.loaded();

            }.bind(this)

        });

        

        // attach events

        this.obj.messageWrapper.addEvent('mouseover', function(){

            this.fx.message.start(0);

        }.bind(this));

        if (this.obj.loadingMessage) {

            this.obj.loadingMessage.setText(this.text.COMMENTS_LOADING);

            this.obj.scroller.addEvents({

                'scroll': this.show.bind(this),

                'mousedown': function(){

                    this.mouseDown = true;

                }.bind(this),

                'mouseup': function(){

                    this.mouseDown = false;

                    this.show();

                }.bind(this)

            });

        }

        this.obj.form.addEvent('submit', this.submitForm.bindWithEvent(this));

        

        // misc

        if (window.ie6) {

            this.obj.messageWrapper.setStyle('zoom', 1);  // fix background issue in ie6

        }

    }

};

