﻿; (function($) {
    $.tooltip = {
        defaults: {
            'class': 'tooltip',
            css: {},
            event: 'mouseover',
            track: true,
            offset: { x: 12, y: 18 }
        },
        setup: function(opt) {$.extend($.tooltip.defaults, opt) }
    }

    var tip = function(src, opt) {

        var self = this;
        var titletag = $('<div>').attr('class', 'title').html(opt.word);
        var texttag = $('<div>').attr('class', 'text').html(opt.text);

        src.removeAttr('title').removeAttr('alt');

        $.data(src, 'tooltip', self);
        self.dst = opt.dst;

        src.bind(opt.event + '.tooltip', over).bind('mouseout.tooltip', out).bind('focus.tooltip', over).bind('blur.tooltip', out).bind('click.tooltip', hide);

        function destroy_timers() {
            if (self.timein) {
                clearTimeout(self.timein);
                delete self.timein
            }
            if (self.timeout) {
                clearTimeout(self.timeout);
                delete self.timeout
            }
        }

        function over(ev) {
            destroy_timers();
            if (self.st == out) { return }
            self.st = over;
            if (!self.dst) {
                self.dst = $('<div>').appendTo(document.body).css({ visibility: 'hidden' });
            }
            self.ev = ev;
            self.timein = setTimeout(show, opt['in'] || 0)
        }

        function show() {
            destroy_timers();
            if (!self.dst) { return }

            self.dst.addClass(opt['class']).css(opt.css).append(titletag).append(texttag);
            if (opt.duration > 0) {
                self.timein = setTimeout(hide, opt.duration);
            }
            if (opt.track) {
                self.dst.css({
                    position: 'absolute',
                    visibility: 'visible'
                });
                src.bind('mousemove.tooltip', move);
                $('body').bind('click.tooltip', hide)
            }

            self.w = self.dst.width();
            self.h = self.dst.height();

            if (opt.onshow) { opt.onshow.apply(self.dst) }
            if (opt.track) { move() }
        }

        function out() {
            destroy_timers();
            if (self.st != over) { return }
            self.timeout = setTimeout(hide, opt['out'] || 0)
        }

        function hide() {
            destroy_timers();
            $('body').unbind('.tooltip');
            $('src').unbind('mousemove.tooltip');
            if (!self.dst) { return }
            self.dst.empty();
            if (opt.onhide) { opt.onhide.apply(self.dst) }
            if (self.dst != opt.dst) {
                self.dst.remove();
                delete self.dst
            }
        }

        function move(ev) {
            if (!ev) { ev = self.ev } else { self.ev = ev }
            if (!self.dst) { return }
            var p = {
                x: ev.pageX + opt.offset.x,
                y: ev.pageY + opt.offset.y,
                w: self.w, h: self.h
            }
            w = window;
            if (navigator.appName.indexOf("Microsoft") != -1) {
                winW = document.body.offsetWidth;
                winH = document.body.offsetHeight;
            } else {
                winW = w.innerWidth - 20;
                winH = w.innerHeight - 20;
            }
            var v = {
                x: w.scrollX, y: w.scrollY,
                w: winW,
                h: winH
            };
            if (p.x + p.w > v.x + v.w) { p.x = v.x + v.w - p.w }
            if (p.y + p.h > v.y + v.h) { p.y = ev.pageY - p.h - opt.offset.y }
            if (p.x < v.x) { p.x = v.x }
            if (p.y < v.y) { p.y = v.y }
            if (p.x + p.w > v.w) { p.x = v.w - p.w; }
            self.dst.css({ top: p.y, left: p.x })
        }
    }

    function setup() {
        return this.each(function() {
            t = $.data(this, 'tooltip');
            if (t) { $.extend(t.opt, opt) }
            return this
        })
    }

    function remove() {
        return
        this.unbind('.tooltip').removeData('tooltip');
    }

    function create(opt) {
        remove.apply(this);
        opt = $.extend({}, $.tooltip.defaults, opt);
        service(this, opt);
    }

    function service(list, opt) {
        var self = this;
        var datalist = [];
        if ($.metadata) {
            var prefix = '';
            var args = 'Words=';
            var i = 0;
            list.each(function() {
                i++;
                src = $(this);
                opt = $.extend({}, opt, src.metadata().tooltip);
                datalist.push({ src: src, opt: opt });
                args += prefix + opt.word;
                prefix = '_*_*_';
            });
            if (args != 'Words=') {
                $.ajax({
                    type: 'POST',
                    url: '/EditorPlugins/Wordlist/Service.asmx/ReadWords',
                    data: args,
                    dataType: 'xml',
                    success: function(xml) {
                        $(xml).find('WordData').each(function() {
                            var parseddbid = $('ID', this).text();
                            var parsedword = $('Word', this).text();
                            var parseddesc = $('Description', this).text();
                            for (var i in datalist) {
                                if (datalist[i].opt.word == parsedword) {
                                    datalist[i].opt.text = parseddesc;
                                    new tip(datalist[i].src, datalist[i].opt);
                                }
                            }
                        });
                        cleanup(datalist);
                    },
                    error: function(objRequest) {
                        cleanup(datalist);
                    }
                });
            }
            else {
                cleanup(datalist);
            }
        }
    }

    function cleanup(datalist) {
        for (var i in datalist) {
            if (!datalist[i].opt || !datalist[i].opt.text) {
                datalist[i].src.attr('class', 'tooltipwordhidden');
            } else {
                datalist[i].src.attr('class', 'tooltipwordready');
            }
        }
    }

    $.fn.tooltip = function(a, o) {
        if (!o && (typeof a != 'string')) {
            o = a;
            a = 'create'
        }
        return (f = ({
            setup: setup,
            remove: remove,
            create: create
        })[a]) && f.apply(this, [o])
    }

})(jQuery);