/**
 * Javascript Class Framework
 * 
 * Copyright (c) 2008 John Resig (http://ejohn.org/blog/simple-javascript-inheritance/)
 * Inspired by base2 and Prototype
 */

(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};
 
  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;
   
    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;
   
    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
           
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
           
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);       
            this._super = tmp;
           
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
   
    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
   
    // Populate our constructed prototype object
    Class.prototype = prototype;
   
    // Enforce the constructor to be what we expect
    Class.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;
   
    return Class;
  };
})();

/*
 * check for user
 *
 */
 
(function($) {
    $.requireFacebookConnected = function(isConnected, callback, extraUrlParams){
        var redir = function(event){
            FB.Connect.requireSession(
                function(){
                    redirUrl = '/account/on_fb_login?continue_path='+encodeURIComponent(location.pathname+location.search);
                    if(extraUrlParams){
                        redirUrl += '&'+extraUrlParams;
                    }
                    location.href = redirUrl;
                }
            );
            return false;
        }
        if(!isConnected){
            redir();
        }
        else{
            callback.apply(this);
        }
    };
    $.fn.userRequired = function(user) {
            return this.each(function(i) {
                $(this).attr("ur_idx", i);
                var overlay = function(event) {
                    // console.debug("event %o %s", event, typeof event);
                    event.preventDefault();
                    remoteModalOverlay(event, "/account/login_overlay?continue_path=" + encodeURI(window.location.pathname));
                };
                if (! bool(user)) {
					$(this).bind('click', overlay);
				} else {
				    $(this).bind('click', function(e) {
				        e.currentUser = user;
				    });
				}
            });
        };

})(jQuery);

/*
 * check to ensure FB extended perms are in place
 *
 */

// (function($) {
//     
//     $.fn.permsRequired = function(fb_api) {
//             return this.each(function(e) {
//                 console.debug("permsRequired attached");
//                 if (fb_api != undefined) {
//                 fb_api.users_hasAppPermission('publish_stream',
//                      function(result) {
//                         // prompt offline permission
//                         console.debug("permission result %o", result);
//                         if (result == 0) {
//                             // render the permission dialog
//                             FB.Connect.showPermissionDialog('publish_stream', function() {
//                                 return true;
//                             });
//                         } else {
//                             console.debug("we have permission!");
//                             return true; // has permissions
//                         }
//                     })
//                 }
//             });
//         }
// 
// })(jQuery);


// (function($) {
//     $.fn.clickOutside = function(selector, callback) {
//         
//         var selector = $(selector);
//         var cb = callback;
//         
//         function checkClick(e, selector) {
// 
//                 var element = $(e.target);
//                 var boundary = selector;
// 
//                 console.debug("checkClick: %o, %o", selector, element);
// 
//                 cont = true;
//                 while (cont) {
//                     if (element == boundary) {
//                         return false;
//                     } else if (element == document) {
//                         cont = false;
//                         return true;
//                     }
//                     else {
//                         element = $(element).parent();
//                     }
//                 }
// 
//         }
//         
//         $(document).bind("mousedown", function(e) {
//             if (checkClick(e, selector)) {
//                 cb();
//             }
//         });
// 
// }})(jQuery);

(function($) {
    $.fn.has = function(selector) {
        return $(this).find(selector).size() > 0
            || $(this).is(selector);
    };
})(jQuery);

(function($) {
    $.fn.exists = function(selector) {
        return $(this).length > 0;
    };
})(jQuery);

(function($) {
    
    $.fn.delay = function(time, callback){
        // Empty function:
        jQuery.fx.step.delay = function(){};
        // Return meaningless animation, (will be added to queue)
        return this.animate({delay:1}, time, callback);
    };
    
})(jQuery);

(function($) {
    $.fn.extend({
      if_: function (cond)
      {
        if ($.isFunction(cond)) { cond = cond.call(this); }
        this.if_CondMet = !!cond;
        return this.pushStack(cond ? this : []);
      },
      else_: function (cond)
      {
        var _this = this.end();
        return _this.if_CondMet ?
                    _this.pushStack([]):
                    _this.if_(arguments.length ? cond : 1);
      }
    });
})(jQuery);


(function($) {
    $.delegate = function(rules) {
      return function(e) {
        var target = $(e.target);
        for (var selector in rules) {
          if (target.is(selector)) return rules[selector].apply(this, $.makeArray(arguments));
        }
      };
    };
})(jQuery);

(function($) {
    $.postJSON = function(url, data, callback) {
        console.debug("callback: %o", callback);
    	$.post(url, data, callback, "json");
    };
})(jQuery);

/*! Copyright (c) 2008 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 */
 
/**
 * Gets the width of the OS scrollbar
 */
(function($) {
	var scrollbarWidth = 0;
	$.getScrollbarWidth = function() {
		if ( !scrollbarWidth ) {
			if ( $.browser.msie ) {
				var $textarea1 = $('<textarea cols="10" rows="2"></textarea>')
						.css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body'),
					$textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>')
						.css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body');
				scrollbarWidth = $textarea1.width() - $textarea2.width();
				$textarea1.add($textarea2).remove();
			} else {
				var $div = $('<div />')
					.css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 })
					.prependTo('body').append('<div />').find('div')
						.css({ width: '100%', height: 200 });
				scrollbarWidth = 100 - $div.width();
				$div.parent().remove();
			}
		}
		return scrollbarWidth;
	};
})(jQuery);

var CommentBoxy = $.extend(Boxy, {});

CommentBoxy.prototype = $.extend(Boxy.prototype, {
    
    offset: 15,
    elem: this.boxy,
    
    setElem: function(elem) {
        this.elem = elem;
    },
    
    getYLimit: function() {
        elem = this.elem;
        sbOffset = $("#share_bar").exists() ? $("#share_bar").outerHeight() : 0;
        var t = elem.get(0).offsetTop + 30; // not sure what this is, todo: remove hackery
        var total = Boxy._viewport().height - t - sbOffset - this.offset * 2;
        // console.debug("getYLimit on %o -- viewport height: %s, size: %s, t: %s, sbOffset: %s, total: %s, box: %o", 
        //     elem, Boxy._viewport().height, this.getFullSize()[1], t, sbOffset, total, this);
        return total;
    },
    
    reanchor: function(side) {
        side = side || 'right';
        var x = side == 'right' ?
            Boxy._viewport().width - this.getSize()[0] - $.getScrollbarWidth() - this.offset :
            this.offset;
        this.moveTo(x, this.offset);
    },
    
    readjustHeight: function() {
        this.checkSize();
    },
    
    limit: function() {
        elem = this.elem;
        var yLimit = this.getYLimit();
        console.debug("limit of %s fired on %o", yLimit, elem);
        elem.css({ height: yLimit, overflowY: "auto" });
    },
    
    unlimit: function() {
        elem = this.elem;
        if (this.orig) this.elem.height(this.orig);
        // console.debug("unlimit fired on %o with orig of %s", elem, this.orig);
        elem.css({ height: "auto", overflowY: "hidden" });
    },
    
    checkSize: function(h) {
        // h = height of element being appended; usually an instance of li.comment
        h = h || 0; 
        elem = this.elem; 
        this.orig = this.elem.height();
        // console.debug("checkSize -- this.elem: %o, h: %s, height: %s, limit: %s", elem, h, this.getFullSize()[1], this.getYLimit());
        if (this.elem.height() + h >= this.getYLimit()) {
            this.limit();
        } else {
            this.unlimit();
        }
    },
    
    dim: function(op) {
        op = op || 0.7;
        this.boxy.animate({ opacity: op });
    },
    
    brighten: function() {
        this.boxy.animate({ opacity: 1.0 });
    }
    
});

var ControlPanelBoxy = $.extend(CommentBoxy, {});

ControlPanelBoxy.prototype = $.extend(CommentBoxy.prototype, {
    reanchorPanel: function() {
        var sbOffset = $("#share_bar").exists() ? $("#share_bar").outerHeight() : 0;
        var y = Boxy._viewport().height - this.getSize()[1] - sbOffset - this.offset;
        this.moveTo(this.offset, y);
    }
});

