/*
 * Align 1.0
 *
 * Copyright (c) 2008 Vendio
 */

/**
 * Get anchor coordinates for a specific jQuery Obj
 * anchor values:
 * 'tl' - top left, 'tc' - top center, 'tr' - top right
 * 'ml' - left center, 'mc' - center of element, 'mr' - middle right
 * 'bl' - bottom-left, 'bc' -  bottom-center, 'br' - bottom-right
 * 
 * @param {String} anchor : anchor point
 * @param {Boolean} local: true to get the position of the anchor relative to the element instead of page coordinates
  * @return {Array} [x, y]
 **/

/* Dimensions */

jQuery.fn.getAnchorXY = function(anchor, local){
    var w, h, doc = false;
    
    var domEl = this.get(0);
    if (domEl === document.body || domEl === document) {
        //if the reference is the document itself get anchor points for the current view
         doc = true;
         var tmpArr = getViewDimensions();
         w = tmpArr[0];
         h = tmpArr[1];
    } else {
        //had to add dimentsions plugin to include borders and paddings
         w = this.outerWidth();
         h = this.outerHeight();
         /*w = this.width();
         h = this.height();*/
    }
  
    var x = 0, y = 0;
    
    switch ((anchor || "mc").toLowerCase()) {
        case "mc":
            x = Math.round(w * .5);
            y = Math.round(h * .5);
            break;
        case "tc":
            x = Math.round(w * .5);
            y = 0;
            break;
        case "ml":
            x = 0;
            y = Math.round(h * .5);
            break;
        case "mr":
            x = w;
            y = Math.round(h * .5);
            break;
        case "bc":
            x = Math.round(w * .5);
            y = h;
            break;
        case "tl":
            x = 0;
            y = 0;
            break;
        case "bl":
            x = 0;
            y = h;
            break;
        case "br":
            x = w;
            y = h;
            break;
        case "tr":
            x = w;
            y = 0;
            break;
    }
    
	if (local === true) {
        return [x, y];
    }
	
    //if we're talkin about the whole document calculate scrolling offsets   
    if (doc) {
		var o = {
			left: domEl.body.scrollLeft,
			top: domEl.body.scrollTop
        };
        
        //console.log(o);
    }
	else {
		var o = this.offset();
	}
	
    return [x + o.left, y + o.top];
     
    function getViewDimensions() {
            if(jQuery.browser.msie){
                return [document.body.clientWidth, document.body.clientHeight];
            }else{
                return [self.innerWidth, self.innerHeight];
            }
    }
};

/**
 * Sets xy page coordinates for an element
 * @param x page x coord.
 * @param y page y coord
 * @return {jQuery}
 */
 
jQuery.fn.setXY = function(x, y) {
    if(this.css("position") !== "absolute")
    {
        this.css("position", "relative");
        var pts = this.translatePoints(x, y);
    } else {
        var pts = {left: x, top: y};
    }
	
	if (pts.left !== false) {
    	this.css('left', pts.left + "px" );
    }
			
	if (pts.top !== false) {
    	this.css('top', pts.top + "px" );
    }
    
    return this;
};

/**
 * Translates screen coordinates into css coordinates
 * @param {int} x page x coordinate
 * @param {int} y page y coordinate
 * @return {Object} {left, top} CSS coordinates
 */


jQuery.fn.translatePoints = function(x, y) {
        var p = this.css('position');
        var o = this.offset();

        var l = parseInt(this.css('left'), 10);
        var t = parseInt(this.css('top'), 10);

        if(isNaN(l)){
            l = (p == "relative") ? 0 : this.get(0).offsetLeft;
        }
        if(isNaN(t)){
            t = (p == "relative") ? 0 : this.get(0).offsetTop;
        }

        return {left: (x - o.left + l), top: (y - o.top + t)};
    };

/**
 * Aligns an element(selection) relative to another(reference) using anchor points
 * 
 * anchor values:
 * 'tl' - top left, 'tc' - top center, 'tr' - top right
 * 'ml' - left center, 'mc' - center of element, 'mr' - middle right
 * 'bl' - bottom-left, 'bc' -  bottom-center, 'br' - bottom-right
 *  
 * 
 * @param {String} sel_anchor  selection anchor point, default - 'mc'
 * @param {String} ref_anchor  reference anchor point, default - 'mc'
 * @param {Object} offset  offsets position by {x, y}
 * @return {jQuery}
 **/

jQuery.fn.align = function(ref, offset, ref_anchor, sel_anchor) {
    offset = offset || {x: 0, y: 0};
	
    // veryfing input
    if(!ref) ref = document;
    
    var jqRef = jQuery(ref);
    if(jqRef.length > 1) jqRef = jqRef.eq(0);
        
    if(!jqRef.length) { 
        throw('Illegal align reference') 
    };
    
	var anchorRef = jqRef.getAnchorXY(ref_anchor, false);
	
    return this.each(function() {
		var jqSel = jQuery(this);
        var anchorSel = jqSel.getAnchorXY(sel_anchor, true);
	
        var x = anchorRef[0] - anchorSel[0] + offset.x;
        var y = anchorRef[1] - anchorSel[1] + offset.y;
		
		jqSel.setXY(x, y);			                
    });
};




