﻿/*

we add a change event to each element that is matched for validation.
we validate it based on the validation type. If it's valid we add the specified class
if not then we don't
*/


(function($) {


    $.fn.vTooltip = function(options) {



        if (this.length > 1) {
            alert("vTooltip can only be applied to a single DOM element");
            return false;
        }

        //an element can only have one instance of a datasource
        return this.each(function() {
            var element = $(this);
            var lookfor = "vTooltip-" + options.applyto;
            // Return early if this element already has a plugin instance
            if (element.data(lookfor)) {
                vLog('vTooltip', 'already instantiated!' + lookfor);
                return;
            }
            // pass options to plugin constructor
            var vrs = new vTooltip(this, options);
            // Store plugin object in this element's data
            element.data(lookfor, vrs);
            $(document).trigger('vnx-reg-vtooltip', vrs);

        });
    };





    var vTooltip = function(element, options) {
        var $element = element;
        var Config = {
            applyto: 'vtip',
            tipID: '',
            tipclass: 'tooltip',
            type: 'inline',
            url: '',
            top: 15,
            left: 15,
            track: true

        };
        if (options) {
            jQuery.extend(Config, options);
        };
        var Us = this;

        var $opentip = null;

        function viewport() {
            return {
                x: $(window).scrollLeft(),
                y: $(window).scrollTop(),
                cx: $(window).width(),
                cy: $(window).height()
            };
        }

        this.applyto = function() {
            return Config.applyto;
        }

        //we get to initialise all the elements with this particular tooltip class
        this.initialisetips = function() {
            $('[data-vtip=' + Config.applyto + ']').each(function() {
                var $t = $(this);
            });
            //make sure there is a dom element created if we are not using poppup
            if (Config.type != "popup" && $('#vtipdiv-' + Config.applyto).length == 0) {
                jQuery("<div>", { "id": "vtipdiv-" + Config.applyto, "class": Config.tipclass, css: { position: "absolute", display: "none", zIndex: '99'} }).appendTo("body");
            }
            vLog('vTooltip', 'Initialised ' + Us.applyto());
        }

        this.position = function(event) {

            if ($opentip == null) {
                $(document.body).unbind('mousemove', this.position);
                return;
            }

            // remove position helper classes
            $opentip.removeClass("viewport-right").removeClass("viewport-bottom");

            var moved = false;
            var curpos = $opentip.offset();
            var addingaclass = "";

            var left = 0;
            var top = 0;


            if (event) {
                // initial position based on the event data
                left = event.pageX + Config.left;
                top = event.pageY + Config.top;

                //vLog('tt', 'Start left:' + left + ' top:' + top);
            }

            var v = viewport();

            //alert("viewx" + v.cx + " tipwidth " + $opentip.outerWidth());
            var vx = v.x + v.cx;
            var vw = left + $opentip.outerWidth();
            //vLog('tt', 'Need to Adjust?:' + vx + ' lt ' + vw + '(curposleft:' + left + ' width:' + $opentip.outerWidth() + ')');

            // check horizontal position to see if we need to modify it because it's too close to the edge
            if (v.x + v.cx < left + $opentip.outerWidth()) {
                left -= $opentip.outerWidth() + 20 + Config.left;
                addingaclass = "viewport-right";

            }
            // check vertical position
            if (v.y + v.cy < curpos.top + $opentip.outerHeight()) {
                top -= $opentip.outerHeight() + 20 + Config.top;
                addingaclass = "viewport-bottom";
            }

            if (curpos.left != left || curpos.top != top) moved = true;

            //if changed
            if (moved) {
                //vLog('tt', 'UPDATING?' + left + ' lt ' + top);
                $opentip.css({
                    left: left + 'px',
                    right: 'auto',
                    top: top + 'px'
                }).addClass(addingaclass);
            }

        }

        this.opentip = function(event, $elm) {
            //update the data for the div if needed
            var $tipdiv = $("#vtipdiv-" + Config.applyto);
            switch (Config.type) {
                case "inline":
                    var content = $elm.attr('data-vtip-tip');
                    if (content == "" || content == null) return;
                    $tipdiv.html(content);
                    break;
                case "ajax":
                    alert("get remote tip data");
                    break;
                case "popup":
                    //no data needed, we just use the supplied div
                    $tipdiv = $('#' + Config.tipID);
                    break;
            }
            $opentip = $tipdiv;

            this.position(event);

            $tipdiv.css({ display: 'block' });
            //are we tracking this?
            if (Config.track) $(document.body).bind('mousemove', this.position);

        }

        this.closetip = function($elm) {
            if ($opentip != null) {
                $opentip.css({ display: 'none' });
                $(document.body).unbind('mousemove', this.position);
                $opentip = null;
            }

        }

        //now actually perform the first initialisation
        Us.initialisetips();

    };

})(jQuery);
