var LinkHandler = function(args) { this.init(args); }
jQuery.extend(LinkHandler.prototype, {
    init: function(args) {
        this._anchor_elm = args.anchor;
        this._anchor     = $(this._anchor_elm);
        this._type       = args.type;
        this._action     = this._anchor.attr('href');

        var self = this;
        this._anchor.click(function(){self.click();return false;});

        var tmp = {
            cache_html : true,
            method      : 'get',
            success     : null,
            error       : null,
            data        : {}
        };
        $.extend(tmp, args);

        this._cache_html = tmp.cache_html;
        this._method  = tmp.method;
        this._success = tmp.success;
        this._error   = tmp.error;

        this._data = {
            remote : 1,
            _method : this._method // Needed for IE
        };
        $.extend(this._data, tmp.data);
    },

    click : function(type) {
        switch(this._type) {
          case 'json' :
            this._json_ajax_wrapper();
            break;
          case 'html' :
            var cache = $('body').data(this._cache_key());
            $.is_empty(cache) ? this._html_ajax_wrapper() : this._call_fn(this._success(cache));
            break;
          default:
            $.warn('Type '+ this._type +' not recognized!')
        }
        return false;
    },

    //
    // PRIVATE-ish
    //
    _cache_key : function(){
        return this._method + this._action;
    },

    // For JSON ajax requests, we have a slightly different way of processing results:
    // Success : Because the ajax call can succeed but the processing of that call may have
    //           failed, look for json.failure. If there, display the error and return the
    //           value of our callback (or false). Otherwise, return value of success
    //           callback (or true).
    // Error   : Display the error returned in the response and return the value of our
    //           callback (or false)
    // Params  : type = get | post | push | delete
    _json_ajax_wrapper: function() {
        try {
            var self = this;
            $.ajax({
                url      : self._action,
                type     : self._method,
                data     : self._data,
                dataType : 'json',
                success  : function(json) {
                    // B/c of how we process json requests in back, we only know if we failed if
                    // failure = true. All this means is that we need to look for failure before
                    // assuming success
                    if ( json.failure ) {
                        self._on_json_failure(json.error, self._error, json);

                    } else {
                        return self._call_fn(self._success, json);
                    }
                },
                error : function(resp){
                    self._on_json_failure(resp.error, self._error, resp);
                }
            });
        } catch(e) {
            $.warn(e);
        }
    },

    // For HTML ajax requests, we have a slightly different process than the json ajax stuff.
    // Success : our only check is to make sure we did not get a full html doc returned. If we
    //           did not, then we have no other real error checking, so just look for a callback.
    // Error   : show a generic "we're sorry" error and look for an error callback.
    // Params  : type     = get | post | push | delete
    //           settings = success (callback), error (callback)
    _html_ajax_wrapper: function() {
        try {
            var self = this;
            $.ajax({
                url      : self._action,
                type     : self._method,
                data     : self._data,
                dataType : 'html',
                success  : function(html) {
                    if ( html.match('</html>') ) {
                        $.warn('We got back an entire page! Show error fn or we are sorry notice.');
                        return self._call_fn(self._error, "");

                    } else {
                        if ( self._cache_html )
                            $('body').data(self._cache_key(), html);

                        return self._call_fn(self._success(html));
                    }
                },
                error : function(resp){
                    self._show_we_are_sorry(resp);

                    // Callback?
                    return self._call_fn(self._error, resp);
                }
            });
        } catch(e) {
            $.warn('caught unknown exception');
            $.warn(e);
        }
    },

    _on_json_failure : function(resp_err, fn, fn_args) {
        // we should handle error messages here if we ever decide to do this
        //if ( this._handle_errors ) {
        //    var error = this.get_error_list_item(resp_err);
        //    this.display_errors(error);
        // }

        // Callback?
        return this._call_fn(fn, fn_args);
    },

    _call_fn : function(fn, args) {
        if ( jQuery.isFunction(fn) ) {
            fn(args);
            return true;
        }
        return false;
    },

    _show_we_are_sorry : function(resp) {
        //if ( !this._handle_errors ) return;
        //var notice = new NoticeHandler(null,'error','We\'re sorry, but it seems there was a problem with your request.');
        //notice.show();
    }
});
