
    /*
        IMAGE HINTER
        JQUERY PLUGIN
        VERSION: 1.0
        BY VAD 'sPACEYE' KAKOUKA
        14-12-2010

    */

(function($){
    $.fn.hintMe = function(hintOptions) {

        var options = {
            coords : new Array(),
            color : '',
            hint : '',
            hintPadding : {x:12,y:12},
            visualize : false,
            hintStatic : false,
            hintPlacard : false,
            delay : 500,
            fadeInTime : 100,
            opacity : 0.8,
            font : '"Helvetica Neue",Arial,sans-serif',
            fontsize : '11px',
            fontcolor : '#FFF',
            padding : 6,
            corners : 3
        };

        // add user submitted options
        if ( hintOptions ) { $.extend(options,hintOptions); }

        return this.each(function() {

            // image jQuery object
            this.obj = $(this);

            if ( this.obj.length && $(this.obj).is('img') ) {

                this.options = options;
                this.options.imageHint;
                this.options.defaultHint;
                this.originalHints = {
                    title:'',
                    alt:''
                };

                this.hint = '';
                this.oldHint = '';

                // our coords set with hints
                this.coords = ( typeof(this.options.coords) == 'object' && (this.options.coords instanceof Array) ) ? this.options.coords : new Array();
                // if no coords
                this.defaultHint = ( this.options.hint ) ? this.options.hint : '';
                // original stuff
                this.originalHints.title = ( $(this.obj).attr('title') ) ? $(this.obj).attr('title') : '';
                this.originalHints.alt = ( $(this.obj).attr('alt') ) ? $(this.obj).attr('alt') : '';
                // remove 'em attributes
                $(this.obj).removeAttr('title');
                $(this.obj).removeAttr('title');

                // determing original string
                if ( this.originalHints.alt.length > 0 && this.originalHints.title.length == 0 ) {
                    this.originalHints.def = this.originalHints.alt;
                }
                else if ( this.originalHints.title.length > 0 && this.originalHints.alt.length == 0 ) {
                    this.originalHints.def = this.originalHints.title;
                }
                else if ( this.originalHints.title.length > 0 && this.originalHints.alt.length > 0 ) {
                    this.originalHints.def = this.originalHints.alt;
                }
                else {
                    this.originalHints.def = '';
                }

                this.defaultHint = ( this.defaultHint.replace(/\s/).length > 0 ) ? this.defaultHint : this.originalHints.def;

                // okay honcho
                if ( this.coords.length == 0 ) {
                    this.coords.push([[0,0],[$(this.obj).width(),$(this.obj).height()],this.defaultHint]);
                    this.options.hintStatic = true;
                }

                // shows the hint DOM element with data
                this.showHint = function(e) {

                    // get hint text
                    this.hint = this.getHint(e);

                    if ( this.oldHint !== this.hint ) {
                        // hide everything
                        this.hideHint();
                    }
                    // if there's a hint text and we're on the roll
                    if ( this.hint.length ) {

                        // update DOM with hint text
                        this.imageHint.html(this.hint);
                        // get hint coords
                        var hintCoords = ( this.options.hintStatic && this.options.hintPlacard ) ? this.getHintPlacardCoords() : this.getHintCoords(e);
                        // update DOM with hint's new coords
                        this.imageHint.css({'top':hintCoords.y,'left':hintCoords.x});

                        if ( !this.timeout ) {

                            var self = this;

                            // store timeout handler
                            this.timeout = setTimeout(function(){
                                // store previous value
                                self.oldHint = self.imageHint.html();
                                // start animation
                                self.imageHint.fadeIn(300);
                                // unset timeout
                                self.timeout = null;
                            },self.options.delay);
                        }
                    }
                }

                // calculates
                this.getHintPlacardCoords = function() {

                    this.offset = $(this.obj).offset();
                    // double the padding value
                    contentPadding = this.options.padding * 2;
                    // set the new width respecting the padding
                    this.imageHint.width(this.obj.width() - contentPadding);
                    // clear the shadow and gradient
                    this.imageHint.css({'-moz-box-shadow':'','-webkit-box-shadow':'','background':this.options.color});

                    // return object
                    return {x:this.offset.left,y:this.offset.top + (this.obj.height() - ( this.imageHint.height() + contentPadding ) )};
                };

                // calculates
                this.getHintCoords = function(e) {

                    var cx,cy;
                    var viewport = {
                        h: $(window).height(),
                        w: $(window).width()
                    };
                    var hintGeometry = {
                        h: this.imageHint.height() + this.options.padding * 2,
                        w: this.imageHint.width() + this.options.padding * 2
                    }
                    var correction = 0;

                    this.offset = $(this.obj).offset();

                    // map or static
                    if ( this.options.hintStatic ) {
                        cx = this.offset.left + this.obj.width() + 4;
                        cy = this.offset.top + Math.round( this.obj.height()/2 ) - Math.round(this.imageHint.height()/2) - this.options.padding;
                    }
                    else {
                        cx = e.pageX;
                        cy = e.pageY;
                    }

                    cx += this.options.hintPadding.x;
                    cy += ( this.options.hintStatic ) ? 0 : this.options.hintPadding.y;

                    // wow, I hate 'em scrolls
                    if ( cx + hintGeometry.w + 20 >= viewport.w ) {
                        cx -= cx + hintGeometry.w - viewport.w + 20;
                        correction = 4;
                    }

                    // wow, I hate 'em scrolls
                    if ( cy + hintGeometry.h + 10 >= viewport.h ) {
                        cy = e.pageY - hintGeometry.h - correction;
                    }

                    // return object
                    return {x:cx,y:cy};
                };

                // clears and hides the hint DOM element
                this.hideHint = function() {

                    if ( this.timeout ) {
                        clearTimeout(this.timeout);
                        this.timeout = null;
                    }
                    this.oldHint = this.hint;
                    this.imageHint.html('').css('display','none');
                }

                // attaches hint
                this.addPlaceholderToDOM = function() {

                    this.hintClassName = "imageHinter" + Math.floor(Math.random()*2000);

                    // wrap image into div
                    this.obj.wrap("<span></span>");
                    // bgcolor?
                    if ( this.options.hintPlacard || this.options.color.length ) {
                        this.options.color = ( this.options.color.length ) ? 'background-color:' + this.options.color : 'background-color:#000';
                    }
                    else {
                        this.options.color = 'background: -webkit-gradient(linear,left bottom,left top,color-stop(0.45, rgb(31,30,31)),color-stop(1, rgb(102,102,102))); background:-moz-linear-gradient(center bottom,rgb(31,30,31) 45%,rgb(102,102,102) 100%)';
                    }
                    // build
                    this.imageHint = $('<div style = "' + this.options.color + '">').css(
                        {
                            'margin': 0,
                            'padding' : this.options.padding,
                            'display' : 'none',
                            'position' : 'absolute',
                            'z-index':'99',
                            'font-family' : this.options.font,
                            'font-size' : this.options.fontsize,
                            'font-weight' : 'normal',
                            'color' : this.options.fontcolor,
                            '-moz-border-radius' : this.options.corners,
                            'border-radius' : this.options.corners,
                            'opacity' : this.options.opacity,
                            '-moz-box-shadow' : '0 1px 2px rgba(0, 0, 0, 0.5)',
                            '-webkit-box-shadow' : 'rgba(0, 0, 0, 0.496094) 0px 1px 2px',
                            'white-space' : ( this.options.hintPlacard ) ? 'wrap' : 'nowrap'
                    });
                    // append to the end of body
                    this.imageHint.appendTo(this.obj.parent());

                    if ( this.options.hintStatic && this.options.hintPlacard ) {
                        // no selection, thanks
                        this.imageHint.bind('mousedown',function(){return false;});
                        this.imageHint.css({'cursor':'default'});
                    }

                }


                // visualizes coords
                this.visualizeCoords = function() {

                    var self = this;

                    if ( this.obj[0].naturalWidth == 0) {
                        this.visualizeTimeout = setTimeout(function(){
                            self.visualizeCoords();
                        },1000);
                    }
                    else {

                        this.visualizeTimeout = null;

                        if ( this.options.visualize ) {

                            for ( i = 0; i < this.coords.length; i++ ) {


                                var left = ( this.coords[i][0][0] < this.coords[i][1][0] ) ? this.coords[i][0][0] : this.coords[i][1][0];

                                var right = ( this.coords[i][1][0] > this.coords[i][0][0] ) ? this.coords[i][1][0] : this.coords[i][0][0];
                                var top = ( this.coords[i][1][1] > this.coords[i][0][1] ) ? this.coords[i][1][1] : this.coords[i][0][1];
                                var bottom = ( this.coords[i][0][1] < this.coords[i][1][1] ) ? this.coords[i][0][1] : this.coords[i][1][1];

                                var width = right - left;
                                var height = top - bottom;

                                var leftpos = ( right > left ) ? left : right;
                                var toppos = ( top > bottom ) ? bottom : top;

                                leftpos += this.obj.offset().left;
                                toppos += this.obj.offset().top;

                                $('<div>').html(left).css({'z-index':'4','font-size':'8px','color':'#FFFFFF','margin':'0','padding':'0','opacity':'0.9','border':'1px #FFFFFF solid','font-weight':'normal','background':'#000000','position':'absolute','display':'block','left':leftpos,'top':toppos}).width(width).height(height).appendTo(this.parentNode);

                            }
                        }
                    }
                }

                this.isMouseIn = function(e) {

                    this.offset = this.obj.offset();
                    return ( (e.pageX >= this.offset.left && e.pageX < this.offset.left + this.obj.width() ) && (e.pageX >= this.offset.top && e.pageY < this.offset.top + this.obj.height()) );
                }

                this.getHint = function(e) {

                    if ( this.options.hintStatic ) return this.defaultHint;

                    var offset = $(this.obj).offset();
                    var x = e.pageX - offset.left;
                    var y = e.pageY - offset.top;

                    if ( typeof(e.target) != 'undefined' ) {

                        for ( i = 0; i < this.coords.length; i++ ) {

                            var left = ( this.coords[i][0][0] < this.coords[i][1][0] ) ? this.coords[i][0][0] : this.coords[i][1][0];
                            var right = ( this.coords[i][1][0] > this.coords[i][0][0] ) ? this.coords[i][1][0] : this.coords[i][0][0];
                            var top = ( this.coords[i][1][1] > this.coords[i][0][1] ) ? this.coords[i][1][1] : this.coords[i][0][1];
                            var bottom = ( this.coords[i][0][1] < this.coords[i][1][1] ) ? this.coords[i][0][1] : this.coords[i][1][1];

                            if ( x > 0 && y > 0 && x >= left && y >= bottom && x <= right && y <= top ) {

                                return this.coords[i][2];
                            }
                        }
                    }

                    return '';
                }

                if ( this.options.visualize ) {this.visualizeCoords();}

                // add hint placeholder to DOM
                this.addPlaceholderToDOM();

                var self = this;

                // add event handlers
                $(this.obj).bind('mousemove', function(e){
                    //setTimeout(function(){ nameCheck(name,key);}, 3000);
                    self.showHint(e);
                });

                $(this.obj.parent()).bind('mouseleave', function(e){
                    self.hideHint();
                });
            }
        });
    };
})(jQuery)

