/*
Author: James Punteney
http://www.punteney.com

-------------------
Attribution-Share Alike 3.0 United States
You are free:
	* to Share — to copy, distribute, display, and perform the work
	* to Remix — to make derivative works
Under the following conditions:
	* Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
	* Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license.
	* For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page.
	* Any of the above conditions can be waived if you get permission from the copyright holder.
	* Apart from the remix rights granted under this license, nothing in this license impairs or restricts the author's moral rights.
		
http://creativecommons.org/licenses/by-sa/3.0/us/
*/
YAHOO.namespace ("JP.borders"); 


/* Change these settings to match your needs */
YAHOO.JP.borders.default_settings = {
    'top_border_src': '/IMAGES/pic_frame_horizontal.jpg',
    'bottom_border_src': '/IMAGES/pic_frame_horizontal.jpg',
    'left_border_src': '/IMAGES/pic_frame_vertical.jpg',
    'right_border_src': '/IMAGES/pic_frame_vertical.jpg',

    'css': {
        'float': 'right',
        'margin-left': '5px'
    }
};
/* End of settings */




YAHOO.JP.borders.auto = function(settings) {
    if (!settings.top_border_src) {
        settings = YAHOO.JP.borders.default_settings;
    }
	var borders = [];
	var items = [];
	var tags = settings.tags || ['img'];
	var find_class = settings.find_class || 'jp-auto-border'; 
	for (tag in tags) {
	    items = items.concat(YAHOO.util.Dom.getElementsByClassName(find_class, tags[tag]));
	}
	for(var i=0, item; item=items[i]; i++) {
	    borders[i] = new YAHOO.JP.borders.Border(item, settings);   
    }
};

YAHOO.JP.borders.Border = function(el, settings) {
    if (el) {
        this.init(el, settings); 
    }
};

// Main border object
YAHOO.JP.borders.Border.prototype = {    
    init: function(el, settings) {
        this.el = el;
        var obj = this;
        
        if (!settings) {
            settings = YAHOO.JP.borders.default_settings;
        }
        this.properties = settings.properties;
        if (!this.properties) {
            this.properties = {};
        }
        this.css = settings.css;
        if (!this.css) {
            this.css = {};
        }
        
        this.borders = {'top': {}, 'bottom':{}, 'left':{}, 'right':{} };
        this.borders_not_loaded = true;
        for (border in this.borders) {
            this.borders[border].loaded = false;
            this.borders[border].src = settings[border+'_border_src'] || YAHOO.JP.borders.default_settings[border+'_border_src'];
            this.borders[border].image = new Image();
            this.borders[border].size = 0;
            var callback_fn = border+'_loaded';
            YAHOO.util.Event.addListener(this.borders[border].image, 'load', this[callback_fn], obj, true);
            this.borders[border].image.src = this.borders[border].src;          
        }
        this.borders_displaying = false;
    },

    top_loaded: function(e, obj) {
        this.border_loaded(e, obj, 'top');  
    },

    bottom_loaded: function(e, obj) {
        this.border_loaded(e, obj, 'bottom');
    },

    left_loaded: function(e, obj) {
        this.border_loaded(e, obj, 'left');  
    },

    right_loaded: function(e, obj) {
        this.border_loaded(e, obj, 'right');  
    },

    border_loaded: function(e, obj, border) {
        if(border == 'top' || border=='bottom') {
            var size =  this.borders[border].image.height;
        } else {
            var size =  this.borders[border].image.width;
        }
        this.borders[border].size = size;
        this.borders[border].loaded = true;
        this.load_frame();
    },
    
    
    load_frame: function() {
        var all_borders_loaded = false;
        for (border in this.borders) {
            if (this.borders[border].loaded) {
                all_borders_loaded = true;
            } else {
                all_borders_loaded = false;
                break;   
            }
        }
        if(all_borders_loaded && !this.borders_displaying) {
            this.borders_displaying = true; //This is to make sure it doesn't double on this if they both finish at the same time
    
            // Determining border size to be used for the width of the layer
            var border_offset = this.properties.border_offset || 0;
            
            for (border in this.borders) {
                this.borders[border].offset = border_offset;
                this.borders[border].total_size = border_offset + this.borders[border].size;
            }
            
            if (this.el.tagName != 'IMG') {
                // It's not an image so we want to honor the formatting of it as much as possible
                // We do this by creating another holder around the object to put the borders on
                // while creating another copy of the el to get all the display settings
                var new_el = document.createElement(this.el.tagName);
                var new_formatted_el = this.el.cloneNode(true);
                YAHOO.util.Dom.setStyle(new_formatted_el, 'margin', 0); //Resetting margins in case they were set to keep placement without the borders
                new_el.appendChild(new_formatted_el);
            } else {
                var new_el = this.el.cloneNode(true);
                 //Resetting styles that would cause issues with the borders
                YAHOO.util.Dom.setStyle(new_el, 'margin', 0);
                YAHOO.util.Dom.setStyle(new_el, 'border', 'none'); //Resetting margins in case they were set to keep placement without the borders
                YAHOO.util.Dom.setStyle(new_el, 'padding', 0); //Resetting margins in case they were set to keep placement without the borders
            }
            // Creating the divs to hold the image and border divs
            var div_wrapper = document.createElement('div');
            YAHOO.util.Dom.addClass(div_wrapper, 'jp-auto-border-container');
            var position = this.properties.position || YAHOO.util.Dom.getStyle(this.el, 'position');
            if (position != 'relative' && position != 'absolute') { 
                position = 'relative'; //needs to be relative or absolute to contain the borders, so set to relative by default
            }
            var container_left_styles = {
                'position': position,
                'float': this.properties['float'] || YAHOO.util.Dom.getStyle(this.el, 'float'),
                'overflow': 'hidden',
                'background': 'transparent url('+this.borders.left.src+') repeat-y '+this.borders.left.offset+'px'
            };

            if(position == 'absolute') {
                container_left_styles.left = YAHOO.util.Dom.getStyle(this.el, 'left');
                container_left_styles.right = YAHOO.util.Dom.getStyle(this.el, 'right');
                container_left_styles.top = YAHOO.util.Dom.getStyle(this.el, 'top');
                container_left_styles.bottom = YAHOO.util.Dom.getStyle(this.el, 'bottom');
                container_left_styles.height = (el_height + this.borders.top.total_size + this.borders.bottom.total_size)+'px';
            }
            this.apply_styles(div_wrapper, container_left_styles);

            var right_styles = {
                'padding': this.borders.top.total_size + 'px ' + this.borders.right.size + 'px ' + this.borders.bottom.total_size + 'px ' + this.borders.left.total_size + 'px',
                'background': 'transparent url('+this.borders.right.src+') repeat-y right',
                'float': 'left'
            };
            this.apply_styles(new_el, right_styles);
            div_wrapper.appendChild(new_el);
            
            var div_top = document.createElement('div');
            YAHOO.util.Dom.addClass(div_top, 'jp-auto-border-top');
            var top_styles = {
                'position': 'absolute',
                'left': 0,
                'top': this.borders.top.offset + 'px',
                'height': this.borders.top.size+'px',
                'width': '100%',
                'background': 'transparent url('+this.borders.top.src+') repeat-x'
            };
            this.apply_styles(div_top, top_styles);
            div_wrapper.appendChild(div_top);
    
            var div_bottom = document.createElement('div');
            YAHOO.util.Dom.addClass(div_bottom, 'jp-auto-border-bottom');
            var bottom_styles = {
                'position': 'absolute',
                'left': 0,
                'bottom': this.borders.bottom.offset + 'px',
                'height': this.borders.bottom.size+'px',
                'width': '100%',
                'background': 'transparent url('+this.borders.bottom.src+') bottom repeat-x'
            };
            this.apply_styles(div_bottom, bottom_styles);
            div_wrapper.appendChild(div_bottom);
            
            this.apply_styles(div_wrapper, this.css);
            var replacedNode = this.el.parentNode.replaceChild(div_wrapper, this.el);
            
            if(position == 'absolute') {
                var el_region = YAHOO.util.Dom.getRegion(new_el);
    	        var el_height = el_region.bottom - el_region.top;
                YAHOO.util.Dom.setStyle(div_wrapper, 'height', (el_height + this.borders.top.total_size + this.borders.bottom.total_size)+'px');
            }
        }
        
    },
    
    apply_styles: function(el, styles) {
        for (style in styles) {
            YAHOO.util.Dom.setStyle(el, style, styles[style]);
        }
    }
};


// Having the images get wrapped on page load
YAHOO.util.Event.addListener(window, 'load', YAHOO.JP.borders.auto);
