/*  bear.js - Bear JavaScript Library
*
/*--------------------------------------------------------------------------*/
var _BEARJS_VERSION = '1.2.1';

// Ajax.BearBase - Bear base class
Ajax.BearBase = Class.create();
Object.extend(Object.extend(Ajax.BearBase.prototype, Ajax.Request.prototype), {
    respondToReadyState: function(readyState) {
        var event = Ajax.Request.Events[readyState];
        var transport = this.transport, json = this.evalJSON();

        if (event == 'Complete') {
            // delete 'loading' indication.
            this.options.onLoading = Prototype.emptyFunction;
            try {
            (this.options['on' + this.transport.status]
            || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
            || Prototype.emptyFunction)(transport, json);
            } catch (e) {
                this.dispatchException(e);
            }
            if ((this.getHeader('Content-type') || '').match(/^text\/javascript/i))
            this.evalResponse();
        }
        if (event == 'Complete'){
            this.action(this.transport, json);
        } else {
            try {
            (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
            Ajax.Responders.dispatch('on' + event, this, transport, json);
            } catch (e) {
                this.dispatchException(e);
            }
        }

        /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
        if (event == 'Complete')
        this.transport.onreadystatechange = Prototype.emptyFunction;
    },

    // impletation is required on each child class.
    action: function(req, json) {
        alert('BearBase::action');
    }
});

//  Ajax.Bear() - bear command
Ajax.Bear = Class.create();
Object.extend(Object.extend(Ajax.Bear.prototype, Ajax.BearBase.prototype), {
    action: function(req, json) {
        //print_b(req);
        //print_b(json);
        // post action
        try {
            var result = app._postAction(req, json);
            if (result == false) {return;}
        } catch(e){};
        if (json){
            //post process
            try {
                $('bear_ajax_sign').style.visibility = "visible";
                $('bear_ajax_sign').style.backgroundColor = "blue";
            } catch
            (e) {};
        } else {
            // error - no json
            try {
                print_b("no json", req.responceText);
                $('bear_ajaxlog').innerHTML = req.responseText;
                $('bear_ajax_sign').style.visibility = "visible";
                $('bear_ajax_sign').style.backgroundColor = "red";
                new Effect.ScrollTo($('bear_ajax_sign'));
                new Effect.Pulsate($('bear_ajax_sign'),{duration: 5, to:1.0});
            } catch (e){
                print_b(e);
            }
            return;
        }
        if (json == 'body'){
            eval('json='+req.responseText);
        }
        print_b(json, "AJAX");
        myBear.parser(json);
    }
});

var Bear = Class.create();
Bear.prototype = {
    // app value
    value: $H(null),
    // window id
    bearLastWindowId: 0,
    // initialize()
    initialize: function() {
        // Set onclick event <a> tag with rel=bear
        if (!document.getElementsByTagName){ return; }
        var anchors = document.getElementsByTagName('a');
        // loop through all anchor tags
        for (var i=0; i<anchors.length; i++){
            var anchor = anchors[i];
            var relAttribute = String(anchor.getAttribute('rel'));
            if (anchor.getAttribute('href') && (relAttribute == 'bear')){
                //print_b(anchor, 'bear link');
                anchor.onclick = function () {myBear.bear(this.toString()); return false;}
            } else if(anchor.getAttribute('href') && (relAttribute == 'xbear')){
                //                print_b(anchor, 'xbear link');
                anchor.onclick = function () {xbear(this.toString()); return false;}
            }
        }
        // Set onclick event <form> tag with rel=bear
        var forms = document.getElementsByTagName('form');
        // loop through all anchor tags
        for (var i=0; i<forms.length; i++){
            var _form = forms[i];
            var relAttr = String(_form.getAttribute('rel'));
            // if rel="bear" form
            if (_form.getAttribute('action') && relAttr.toLowerCase().match('bear')){
                var _inputs = _form.getElementsByTagName('input');
                var actionAttr = String(_form.getAttribute('action'));
                var nameAttr = String(_form.getAttribute('name'));
                // change submit button
                for (var j=0; j<_inputs.length; j++){
                    var type = _inputs[j].getAttribute('type');
                    if (type == 'submit'){
                        print_b(_inputs[j], 'bealink');
                        _inputs[j].onclick = new Function ("", 'myBear.bearQuickform("' + actionAttr + '", "' + nameAttr + '"); return false;');
                    }
                }
            }
        }
    },
    //	bear - ajax request
    bear: function(link, async) {
        //sync mode
        async = (typeof(async) == 'boolean') ? async : true;
        // form data
        var _BEAR_FormValue = this.getFormValue();
        //(multiple) ajax request with form value in header.
        var links = link.split(',');
        try {
            var result = app._preAction(link);
            if (result == false){
                return;
            }
        } catch(e){
        };
        // app value data
        var _BEAR_AjaxValue = this.getJSON(app.value);
        links.each(
        function(item, index){
            print_b(async, 'AJAX asynchronous');
            var json = new Ajax.Bear(
            item,{
                method: 'post',
                asynchronous: async,
                onLoading: bearOnLoading,
                onLoaded: bearOnComplete,
                requestHeaders: [
                'X_BEAR_AJAX', 'bear',
                'X_BEAR_APP', _BEAR_AjaxValue,
                'X_BEAR_FORM', _BEAR_FormValue
                ]
            }
            );
        });
    },
    // QuickForm Validation
    bearQuickform: function(url, form) {
        // form data
        var _BEAR_FormValue = this.getFormValue();
        // app value datal
        var _BEAR_AjaxValue = this.getJSON(app.value);
        var json = new Ajax.Bear(
        url,{
            method: 'post',
            asynchronous: true,
            postBody: Form.serialize(form),
            onLoading: bearOnLoading,
            onLoaded: bearOnComplete,
            requestHeaders: [
            'X_BEAR_AJAX', 'quickform',
            'X_BEAR_APP', _BEAR_AjaxValue,
            'X_BEAR_FORM', _BEAR_FormValue
            ]
        }
        );
    },
    getJSON: function(Obj)
    {
        result = $H(Obj).inspect().replace(/\#<Hash:{(.*?)}>/, "{$1}");
        return result;
    },
    // Get JSON of all form
    getFormValue: function()
    {
        var forms = document.getElementsByTagName('form');
        formObj = new Object();
        for (var i=0; i<forms.length; i++){
            var formid = forms[i].getAttribute('id');
            try {
                var form_value = Form.serialize(formid);
                formObj[formid] = form_value;
            } catch(e){
            }
        }
        result = this.getJSON(formObj);
        return result;
    },
    // Get JSON of app value
    getAjaxValue:  function()
    {
        var result = this.getJSON(app.value);
        return result;
    },
    // Obtain window id
    getNewWindowId: function() {
        this.bearLastWindowId++;
        return "bear_window_" + this.bearLastWindowId;
    },
    // Show DOM contents in window
    showContent: function(div_id)
    {
        var win = new Window(this.getNewWindowId(),
        {
            title: div_id,
            width:480,
            height:320,
            resizable: true
        });
        win.setContent(div_id, false, false);
        win.toFront();
        win.setDestroyOnClose();
        win.showCenter();
    },
    // set AJAX Value
    setAjaxValue: function(name, val)
    {
        app.value[name] = val;
    },
    // Bear command parser
    parser: function(json){
        for(var key in json){
            try {
                app[key](json);
            } catch(e){
                print_b(e, 'Error, unknown bear cmd[' + key + '] arg[' + json +']');
            }
        }
        // refresh Bear
        initBear();
    },
    // put form value
    form: function(json){
        var hash = json['form'];
        for (var key in hash){
            try {
                $(key).value = hash[key];
            } catch (e){
                print_b(e, 'form catch');
            }
        }
    },
    // show ajax contents
    html: function(json){
        var hash = json['html'];
        for (var key in hash){
            var div_id = key;
            var div_html = hash[key];
            try {
                var result = app._html(div_id, div_html);
            } catch (e){
                var result = true;
            }
            if (result != false){
                try{
                    if (json['effect']){
                        var effect_method = '_effect_' + json['effect'];
                        try{
                            try{
                                app[effect_method](div_id, div_html);
                            } catch(e) {print_b(e);
                            this[effect_method](div_id, div_html);
                            }
                        }catch(e) {
                            print_b(e, "catch no effect:" + effect_method);
                        };
                    } else {
                        // no effect
                        $(div_id).innerHTML = div_html;
                    }
                }catch(e){
                    print_b(e, 'catch $(div_id).innerHTML');
                }
                try{
                    string = new String(div_html);
                    string.evalScripts();
                }catch(e){
                    print_b(e, 'catch evalScripts:');
                }
            }
        }
    },
    // effect - sub command for "html"
    effect: function(json)
    {
    },
    initEffect: function(div_id)
    {
        try {Element.remove($(div_id + "_new"));} catch(e) {};
        $(div_id).style.opacity = 100;
    },
    // effect - none
    _effect_none: function(div_id, div_html)
    {
        this.initEffect(div_id);
        $(div_id).innerHTML = div_html;
    },
    // effect - appear
    _effect_appear: function(div_id, div_html){
        this.initEffect(div_id);
        $(div_id).style.opacity = 60;
        $(div_id).innerHTML = div_html;
        try {new Effect.Appear($(div_id), { duration:1, from:0.6, to:1.0 });} catch(e){};
    },
    // effect - cross fade
    _effect_cross: function(div_id, div_html){
        var new_node_id = div_id + "_new";
        if ($(new_node_id)){
            $(div_id).innerHTML = $(new_node_id).innerHTML;
            $(div_id).style.opacity = 100;
            Element.remove($(new_node_id));
        }
        new_node = document.createElement('div');
        $(new_node).style.visibility = "hidden";
        $(new_node).style.opacity = 0;
        new_node.id = new_node_id;
        $(new_node).style.position = 'absolute';
        $(new_node).innerHTML = div_html;
        document.body.insertBefore($(new_node),null);
        Position.clone(div_id, new_node);
        $(new_node).style.visibility = "visible";
        try {new Effect.Appear($(div_id), { duration:0.8, from:1.0, to:0.0 });} catch(e){};
        try {new Effect.Appear($(new_node), { duration:0.8, from:0.0, to:1.0 });} catch(e){};
    },
    // Callback option
    callback: function(json){
        var hash = $H(json['callback']);
        var size = hash.toArray().size();
        for (i = 0; i <= size; i++){
            var function_arg = $H(hash[i]).values()
            var function_name = $H(hash[i]).keys().toString();
            var eval_callback = function_name + '(function_arg)';
            try {
                print_b(function_name, 'function name');
                print_b(function_arg, 'function arg');
                eval(eval_callback);
            } catch(e){
                print_b (e, 'callback eval error');
            }
        }
    },
    // Ajax quick form validation
    quickform: function(json){
        var form_id = json['quickform']['form_id'];
        try{
            // user define hook function
            if (app._formError(json['quickform']) == false){
                return;
            }
        }catch (e){
            print_b(e, 'app._formError catch');
        };
        // clear all
        var hash = json['quickform']['rules'];
        for (var key in hash){
            var form_name = hash[key];
            var div_id =  form_id + '_' +form_name + '_' + 'error';
            var div_sign =  form_id + '_' + form_name + '_' + 'sign';
            try{
                $(div_id).innerHTML = "";
            } catch(e){
                //                print_b(e, 'catch div_id innerHTML'  + div_id);
            };
            try{
                $(div_sign).innerHTML = "";
            } catch(e){
                //                print_b(e, 'div_sign innerHTML' + div_sign);
            };
        }
        // error
        var hash = json['quickform']['errors'];
        for (var element_id in hash){
            var error_msg = hash[element_id];
            var div_error =  form_id + '_' + element_id + '_' + 'error';
            var div_sign =  form_id + '_' + element_id + '_' + 'sign';
            var div_html = error_msg;
            // error msg
            print_b("[quickform invalid] element[" + div_error + "] msg[" + div_html + "]");
            try{
                string = new String(div_html);
                string.evalScripts();
                $(div_error).innerHTML = div_html;
                // user define hook function
                try{
                    app._formErrorEffect(div_error, div_sign);
                }catch (e){
                };
            }catch (e){
                print_b(e, 'catch $(div_error).innerHTML');
            };
            // error sign
            try{
                $(div_sign).innerHTML = bear_sign[0];
            }catch (e){
                print_b(e, 'catch $(div_sign).innerHTML');
            };
        }
    },
    // AJAX application Log
    ajaxlog: function(json){
        try {
            $('bear_ajaxlog').innerHTML = json['ajaxlog'];
            new Effect.Appear($('bear_ajax_sign'));
        } catch (e){
        }
    },
    // AJAX errpr
    ajaxerror: function(json){
        try {
            $('bear_ajaxlog').innerHTML = json['ajaxlog'];
            $('bear_ajax_sign').style.visibility = "visibile";
            $('bear_ajax_sign').style.backgroundColor = "yellow";
            new Effect.ScrollTo($('bear_ajax_sign'));
            new Effect.Pulsate($('bear_ajax_sign'),{duration: 5, to:1.0});
        } catch (e){
        }
    },
    // Cross domain iframe bear.js request
    xbear: function(url){
        _bIfm = document.createElement("IFRAME");
        _bIfm.style.display = "none"; //uncmt here for check ifram cmd.
        _bIfm.src = url;
        //Event.observe(_bIfm, 'load', parseFrame, true); // replace jsonp in iframe
        document.body.appendChild(_bIfm);
        setTimeout(function(){document.body.removeChild(_bIfm);},1000);
        return _bIfm;
    },
    // retrun new added hash to query.
    addQuery:  function(url, hash){
        base_url = url.match(/^(.*)[\?]/);
        if (base_url){
            var base_url = base_url[1];
            var query = $H(url.toQueryParams());
            var newq = base_url + '?' + query.merge(hash).toQueryString();
        } else {
            var newq = url + '?' + hash.toQueryString();
        }
        return newq;
    }

}
// on failure at AJAX
function bearOnFailure(req){
    alert("Communication Error.");
}

// on loading at AJAX
function bearOnLoading() {
    try {
        $(bear_loading[0]).innerHTML = bear_loading[1];
        $(bear_loading[0]).style.visibility = "visible";
    } catch (e){
        print_b(e);
    }
}
// on complete at AJAX
function bearOnComplete(rev, json, link, option) {
    try {
        $(bear_loading[0]).innerHTML = "";
        $(bear_loading[0]).style.visibility = "hidden";
    } catch (e){
        print_b(e);
    }
}


/* bear - bear.js AJAX request
/*--------------------------------------------------------------------------*/
function bear(link, async) {
    var async = (typeof(async) == 'boolean') ? async : true;
    try{
        myBear.bear(link, async);
    } catch(e){
        initBear();
        myBear.bear(link, async);
    }
}

/* xbear - bear.js cross domain AJAX request with iFrame
/*--------------------------------------------------------------------------*/
function xbear(url) {
    var xbear_option = { xbear: 1};
    var url = myBear.addQuery(url, $H(xbear_option));
    print_b(url, 'xbear');
    myBear.xbear(url);
}


/* bearform - bear QuickForm with Bear@PHP
/*--------------------------------------------------------------------------*/
function bearform(url, formid) {
    myBear.quickform(url, formid);
}

/* print_r - print object/array in alert
/*--------------------------------------------------------------------------*/
function print_r(input) {
    var ret;
    for(var i in input) {
        ret += "[ "+i+"] = "+input[i] + "\n";
    }
    alert(ret);
}

/* print_b - print object/array in firebug
/*--------------------------------------------------------------------------*/
function print_b(object, label){
    //	return;
    if (navigator.userAgent.toUpperCase().indexOf("FIREFOX") >= 0) {
        try {
            if (label == undefined){
                label = 'log';
            }
            try{
                console.log('['+label+']', object);
            }catch(e){
            };
        }catch(e){
        }
    } else {
        // no fire fox
    }
}

/*  bearInfo - Bear Info
/*--------------------------------------------------------------------------*/
function bearinfo(){
    print_b("bear.js ver." + _BEARJS_VERSION, 'bearinfo');
    print_b(myBear, 'Bear');
    print_b(app, 'App');
}

/*  initBear - Bear initializer
/*--------------------------------------------------------------------------*/
function initBear() {
    myBear = new Bear();
    try { app._refresh();} catch(e){};
}
Event.observe(window, 'load', initBear, false);

