/**
* A class to parse color values
* @author Stoyan Stefanov <sstoo@gmail.com>
* @link   http://www.phpied.com/rgb-color-parser-in-javascript/
* @license Use it if you like it
*/
function RGBColor(color_string) {
    this.ok = false;

    // strip any leading #
    if (color_string.charAt(0) == '#') { // remove # if any
        color_string = color_string.substr(1, 6);
    }

    color_string = color_string.replace(/ /g, '');
    color_string = color_string.toLowerCase();

    // before getting into regexps, try simple matches
    // and overwrite the input
    var simple_colors = {
        aliceblue: 'f0f8ff',
        antiquewhite: 'faebd7',
        aqua: '00ffff',
        aquamarine: '7fffd4',
        azure: 'f0ffff',
        beige: 'f5f5dc',
        bisque: 'ffe4c4',
        black: '000000',
        blanchedalmond: 'ffebcd',
        blue: '0000ff',
        blueviolet: '8a2be2',
        brown: 'a52a2a',
        burlywood: 'deb887',
        cadetblue: '5f9ea0',
        chartreuse: '7fff00',
        chocolate: 'd2691e',
        coral: 'ff7f50',
        cornflowerblue: '6495ed',
        cornsilk: 'fff8dc',
        crimson: 'dc143c',
        cyan: '00ffff',
        darkblue: '00008b',
        darkcyan: '008b8b',
        darkgoldenrod: 'b8860b',
        darkgray: 'a9a9a9',
        darkgreen: '006400',
        darkkhaki: 'bdb76b',
        darkmagenta: '8b008b',
        darkolivegreen: '556b2f',
        darkorange: 'ff8c00',
        darkorchid: '9932cc',
        darkred: '8b0000',
        darksalmon: 'e9967a',
        darkseagreen: '8fbc8f',
        darkslateblue: '483d8b',
        darkslategray: '2f4f4f',
        darkturquoise: '00ced1',
        darkviolet: '9400d3',
        deeppink: 'ff1493',
        deepskyblue: '00bfff',
        dimgray: '696969',
        dodgerblue: '1e90ff',
        feldspar: 'd19275',
        firebrick: 'b22222',
        floralwhite: 'fffaf0',
        forestgreen: '228b22',
        fuchsia: 'ff00ff',
        gainsboro: 'dcdcdc',
        ghostwhite: 'f8f8ff',
        gold: 'ffd700',
        goldenrod: 'daa520',
        gray: '808080',
        green: '008000',
        greenyellow: 'adff2f',
        honeydew: 'f0fff0',
        hotpink: 'ff69b4',
        indianred: 'cd5c5c',
        indigo: '4b0082',
        ivory: 'fffff0',
        khaki: 'f0e68c',
        lavender: 'e6e6fa',
        lavenderblush: 'fff0f5',
        lawngreen: '7cfc00',
        lemonchiffon: 'fffacd',
        lightblue: 'add8e6',
        lightcoral: 'f08080',
        lightcyan: 'e0ffff',
        lightgoldenrodyellow: 'fafad2',
        lightgrey: 'd3d3d3',
        lightgreen: '90ee90',
        lightpink: 'ffb6c1',
        lightsalmon: 'ffa07a',
        lightseagreen: '20b2aa',
        lightskyblue: '87cefa',
        lightslateblue: '8470ff',
        lightslategray: '778899',
        lightsteelblue: 'b0c4de',
        lightyellow: 'ffffe0',
        lime: '00ff00',
        limegreen: '32cd32',
        linen: 'faf0e6',
        magenta: 'ff00ff',
        maroon: '800000',
        mediumaquamarine: '66cdaa',
        mediumblue: '0000cd',
        mediumorchid: 'ba55d3',
        mediumpurple: '9370d8',
        mediumseagreen: '3cb371',
        mediumslateblue: '7b68ee',
        mediumspringgreen: '00fa9a',
        mediumturquoise: '48d1cc',
        mediumvioletred: 'c71585',
        midnightblue: '191970',
        mintcream: 'f5fffa',
        mistyrose: 'ffe4e1',
        moccasin: 'ffe4b5',
        navajowhite: 'ffdead',
        navy: '000080',
        oldlace: 'fdf5e6',
        olive: '808000',
        olivedrab: '6b8e23',
        orange: 'ffa500',
        orangered: 'ff4500',
        orchid: 'da70d6',
        palegoldenrod: 'eee8aa',
        palegreen: '98fb98',
        paleturquoise: 'afeeee',
        palevioletred: 'd87093',
        papayawhip: 'ffefd5',
        peachpuff: 'ffdab9',
        peru: 'cd853f',
        pink: 'ffc0cb',
        plum: 'dda0dd',
        powderblue: 'b0e0e6',
        purple: '800080',
        red: 'ff0000',
        rosybrown: 'bc8f8f',
        royalblue: '4169e1',
        saddlebrown: '8b4513',
        salmon: 'fa8072',
        sandybrown: 'f4a460',
        seagreen: '2e8b57',
        seashell: 'fff5ee',
        sienna: 'a0522d',
        silver: 'c0c0c0',
        skyblue: '87ceeb',
        slateblue: '6a5acd',
        slategray: '708090',
        snow: 'fffafa',
        springgreen: '00ff7f',
        steelblue: '4682b4',
        tan: 'd2b48c',
        teal: '008080',
        thistle: 'd8bfd8',
        tomato: 'ff6347',
        turquoise: '40e0d0',
        violet: 'ee82ee',
        violetred: 'd02090',
        wheat: 'f5deb3',
        white: 'ffffff',
        whitesmoke: 'f5f5f5',
        yellow: 'ffff00',
        yellowgreen: '9acd32'
    };
    for (var key in simple_colors) {
        if (color_string == key) {
            color_string = simple_colors[key];
        }
    }
    // emd of simple type-in colors

    // array of color definition objects
    var color_defs = [
        {
            re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
            example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
            process: function (bits) {
                return [
                    parseInt(bits[1]),
                    parseInt(bits[2]),
                    parseInt(bits[3])
                ];
            }
        },
        {
            re: /^(\w{2})(\w{2})(\w{2})$/,
            example: ['#00ff00', '336699'],
            process: function (bits) {
                return [
                    parseInt(bits[1], 16),
                    parseInt(bits[2], 16),
                    parseInt(bits[3], 16)
                ];
            }
        },
        {
            re: /^(\w{1})(\w{1})(\w{1})$/,
            example: ['#fb0', 'f0f'],
            process: function (bits) {
                return [
                    parseInt(bits[1] + bits[1], 16),
                    parseInt(bits[2] + bits[2], 16),
                    parseInt(bits[3] + bits[3], 16)
                ];
            }
        }
    ];

    // search through the definitions to find a match
    for (var i = 0; i < color_defs.length; i++) {
        var re = color_defs[i].re;
        var processor = color_defs[i].process;
        var bits = re.exec(color_string);
        if (bits) {
            channels = processor(bits);
            this.r = channels[0];
            this.g = channels[1];
            this.b = channels[2];
            this.ok = true;
        }

    }

    // validate/cleanup values
    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
    this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
    this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);

    // some getters
    this.toRGB = function () {
        return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
    }
    this.toHex = function () {
        var r = this.r.toString(16);
        var g = this.g.toString(16);
        var b = this.b.toString(16);
        if (r.length == 1) r = '0' + r;
        if (g.length == 1) g = '0' + g;
        if (b.length == 1) b = '0' + b;
        return '#' + r + g + b;
    }

    // help
    this.getHelpXML = function () {

        var examples = new Array();
        // add regexps
        for (var i = 0; i < color_defs.length; i++) {
            var example = color_defs[i].example;
            for (var j = 0; j < example.length; j++) {
                examples[examples.length] = example[j];
            }
        }
        // add type-in colors
        for (var sc in simple_colors) {
            examples[examples.length] = sc;
        }

        var xml = document.createElement('ul');
        xml.setAttribute('id', 'rgbcolor-examples');
        for (var i = 0; i < examples.length; i++) {
            try {
                var list_item = document.createElement('li');
                var list_color = new RGBColor(examples[i]);
                var example_div = document.createElement('div');
                example_div.style.cssText =
                        'margin: 3px; '
                        + 'border: 1px solid black; '
                        + 'background:' + list_color.toHex() + '; '
                        + 'color:' + list_color.toHex()
                ;
                example_div.appendChild(document.createTextNode('test'));
                var list_item_value = document.createTextNode(
                    ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
                );
                list_item.appendChild(example_div);
                list_item.appendChild(list_item_value);
                xml.appendChild(list_item);

            } catch (e) { }
        }
        return xml;

    }

}

(function ($) {
    var has_VML, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
		canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;

    has_VML = document.namespaces;
    has_canvas = !!document.createElement('canvas').getContext;

    if (!(has_canvas || has_VML)) {
        $.fn.maphilight = function () { return this; };
        return;
    }

    if (has_canvas) {
        hex_to_decimal = function (hex) {
            return Math.max(0, Math.min(parseInt(hex, 16), 255));
        };
        css3color = function (color, opacity) {
            return 'rgba(' + hex_to_decimal(color.substr(0, 2)) + ',' + hex_to_decimal(color.substr(2, 2)) + ',' + hex_to_decimal(color.substr(4, 2)) + ',' + opacity + ')';
        };
        create_canvas_for = function (img) {
            var c = $('<canvas style="width:' + img.width + 'px;height:' + img.height + 'px;"></canvas>').get(0);
            c.getContext("2d").clearRect(0, 0, c.width, c.height);
            return c;
        };
        add_shape_to = function (canvas, shape, coords, options, name, color) {                                    
            
            if (!(color != null && color != "")) {
                color = options.fillColor;            
            }else{
                color = (new RGBColor(color)).toHex().replace("#", "");
            }

            var i, context = canvas.getContext('2d');
            context.beginPath();
            if (shape == 'rect') {
                context.rect(coords[0], coords[1], coords[2] - coords[0], coords[3] - coords[1]);
            } else if (shape == 'poly') {
                context.moveTo(coords[0], coords[1]);
                for (i = 2; i < coords.length; i += 2) {
                    context.lineTo(coords[i], coords[i + 1]);
                }
            } else if (shape == 'circ') {
                context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2, false);
            }
            context.closePath();
            if (options.fill) {
                context.fillStyle = css3color(color, options.fillOpacity);
                context.fill();
            }
            if (options.stroke) {
                context.strokeStyle = css3color(color, options.strokeOpacity);
                context.lineWidth = options.strokeWidth;
                context.stroke();
            }
            if (options.fade) {
                $(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
            }
        };
        clear_canvas = function (canvas) {
            canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
        };
    } else {   // ie executes this code
        create_canvas_for = function (img) {
            return $('<var style="zoom:1;overflow:hidden;display:block;width:' + img.width + 'px;height:' + img.height + 'px;"></var>').get(0);
        };
        add_shape_to = function (canvas, shape, coords, options, name, color) {
            
            var fill, stroke, opacity, e;
            
            var strokeColor = color;

            if (!(color != null && color != "")) {
                color = options.fillColor;                
                strokeColor = options.strokeColor                
            }else{
                color = (new RGBColor(color)).toHex().replace("#", "");
            }
            
            
            

            fill = '<v:fill color="#' + color + '" opacity="' + (options.fill ? options.fillOpacity : 0) + '" />';
            stroke = (options.stroke ? 'strokeweight="' + options.strokeWidth + '" stroked="t" strokecolor="#' + strokeColor + '"' : 'stroked="f"');
            opacity = '<v:stroke opacity="' + options.strokeOpacity + '"/>';
            if (shape == 'rect') {
                e = $('<v:rect name="' + name + '" filled="t" ' + stroke + ' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:' + coords[0] + 'px;top:' + coords[1] + 'px;width:' + (coords[2] - coords[0]) + 'px;height:' + (coords[3] - coords[1]) + 'px;"></v:rect>');
            } else if (shape == 'poly') {
                e = $('<v:shape name="' + name + '" filled="t" ' + stroke + ' coordorigin="0,0" coordsize="' + canvas.width + ',' + canvas.height + '" path="m ' + coords[0] + ',' + coords[1] + ' l ' + coords.join(',') + ' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:' + canvas.width + 'px;height:' + canvas.height + 'px;"></v:shape>');
            } else if (shape == 'circ') {
                e = $('<v:oval name="' + name + '" filled="t" ' + stroke + ' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:' + (coords[0] - coords[2]) + 'px;top:' + (coords[1] - coords[2]) + 'px;width:' + (coords[2] * 2) + 'px;height:' + (coords[2] * 2) + 'px;"></v:oval>');
            }
            e.get(0).innerHTML = fill + opacity;
            $(canvas).append(e);
        };
        clear_canvas = function (canvas) {
            $(canvas).find('[name=highlighted]').remove();
        };
    }

    shape_from_area = function (area) {
        var i, coords = area.getAttribute('coords').split(',');
        for (i = 0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
        return [area.getAttribute('shape').toLowerCase().substr(0, 4), coords];
    };

    options_from_area = function (area, options) {
        var $area = $(area);
        return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
    };

    is_image_loaded = function (img) {
        if (!img.complete) { return false; } // IE
        if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) { return false; } // Others
        return true;
    };

    canvas_style = {
        position: 'absolute',
        left: 0,
        top: 0,
        padding: 0,
        border: 0
    };

    var ie_hax_done = false;
    $.fn.maphilight = function (opts) {
        opts = $.extend({}, $.fn.maphilight.defaults, opts);

        if (!has_canvas && $.browser.msie && !ie_hax_done) {
            document.namespaces.add("v", "urn:schemas-microsoft-com:vml");            
            var style = document.createStyleSheet();
            var shapes = ['shape', 'rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group', 'textbox'];
            $.each(shapes,
				function () {
				    style.addRule('v\\:' + this, "behavior: url(#default#VML); antialias:true");
				}
			);
            ie_hax_done = true;
        }

        return this.each(function () {
            var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
            img = $(this);

            if (!is_image_loaded(this)) {
                // If the image isn't fully loaded, this won't work right.  Try again later.
                return window.setTimeout(function () {
                    img.maphilight(opts);
                }, 200);
            }

            options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));

            // jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
            // So use raw getAttribute instead.
            usemap = img.get(0).getAttribute('usemap');

            map = $('map[name="' + usemap.substr(1) + '"]');

            if (!(img.is('img') && usemap && map.size() > 0)) {
                return;
            }

            if (img.hasClass('maphilighted')) {
                // We're redrawing an old map, probably to pick up changes to the options.
                // Just clear out all the old stuff.
                var wrapper = img.parent();
                img.insertBefore(wrapper);
                wrapper.remove();
                $(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
            }

            wrap = $('<div></div>').css({
                display: 'block',
                background: 'url("' + this.src + '")',
                position: 'relative',
                padding: 0,
                width: this.width,
                height: this.height
            });
            if (options.wrapClass) {
                if (options.wrapClass === true) {
                    wrap.addClass($(this).attr('class'));
                } else {
                    wrap.addClass(options.wrapClass);
                }
            }
            img.before(wrap).css('opacity', 0).css(canvas_style).remove();
            if ($.browser.msie) { img.css('filter', 'Alpha(opacity=0)'); }
            wrap.append(img);

            canvas = create_canvas_for(this);
            $(canvas).css(canvas_style);
            canvas.height = this.height;
            canvas.width = this.width;

            mouseover = function (e) {
                var shape, area_options;
                var id = this.getAttribute('id');                
                area_options = options_from_area(this, options);
                if (
					!area_options.neverOn
					&&
					!area_options.alwaysOn
				) {
                    shape = shape_from_area(this);

                    
                    var color = document.getElementById(id).style.color;

                    add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted", color);
                    if (area_options.groupBy) {
                        var areas;
                        // two ways groupBy might work; attribute and selector
                        if (/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
                            areas = map.find('area[' + area_options.groupBy + '="' + $(this).attr(area_options.groupBy) + '"]')
                        } else {
                            areas = map.find(area_options.groupBy);
                        }
                        var first = this;
                        areas.each(function () {
                            if (this != first) {
                                var subarea_options = options_from_area(this, options);
                                if (!subarea_options.neverOn && !subarea_options.alwaysOn) {
                                    var shape = shape_from_area(this);

                                    var id = this.getAttribute('id');
                                    var color = document.getElementById(id).style.color;

                                    add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted", color);
                                }
                            }
                        });
                    }
                    // workaround for IE7, IE8 not rendering the final rectangle in a group
                    if (!has_canvas) {
                        $(canvas).append('<v:rect></v:rect>');
                    }
                }                                   
            }

            $(map).bind('alwaysOn.maphilight', function () {
                // Check for areas with alwaysOn set. These are added to a *second* canvas,
                // which will get around flickering during fading.
                if (canvas_always) {
                    clear_canvas(canvas_always)
                }
                if (!has_canvas) {
                    $(canvas).empty();
                }
                $(map).find('area[coords]').each(function () {
                    var shape, area_options;
                    area_options = options_from_area(this, options);
                    if (area_options.alwaysOn) {
                        if (!canvas_always && has_canvas) {
                            canvas_always = create_canvas_for(img.get());
                            $(canvas_always).css(canvas_style);
                            canvas_always.width = img.width();
                            canvas_always.height = img.height();
                            img.before(canvas_always);
                        }
                        area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
                        shape = shape_from_area(this);

                        var id = this.getAttribute('id');
                        var color = document.getElementById(id).style.color;

                        if (has_canvas) {
                            add_shape_to(canvas_always, shape[0], shape[1], area_options, "", color);
                        } else {
                            add_shape_to(canvas, shape[0], shape[1], area_options, "", color);
                        }
                    }
                });
            });

            $(map).trigger('alwaysOn.maphilight').find('area[coords]')
				.bind('mouseover.maphilight', mouseover)
				.bind('mouseout.maphilight', function (e) { clear_canvas(canvas); }); ;

            img.before(canvas); // if we put this after, the mouseover events wouldn't fire.

            img.addClass('maphilighted');
        });
    };


    function ToolTip(id, funcao) {
        var meu_elemento = $("#"+id); 
        meu_elemento.trigger(funcao);         
    }

    $.fn.maphilight.defaults = {
        fill: true,
        fillColor: '000000',
        fillOpacity: 0.2,
        stroke: true,
        strokeColor: 'ff0000',
        strokeOpacity: 1,
        strokeWidth: 1,
        fade: true,
        alwaysOn: false,
        neverOn: false,
        groupBy: false,
        wrapClass: true
    };
})(jQuery);

