﻿$.fn.shadow = function(action, options, refreshOnly) {
    /// <summary>
    /// Applies a drop shadow to an element by 
    /// underlaying a <div> underneath the element(s)
    ///
    /// Note the shadow is not locked to the element
    /// so if the element is moved the shadow needs
    /// to be reapplied.    
    /// </summary>    
    /// <param name="action" type="string">
    /// optional - hide, remove
    /// can also be the options parameter if action is omitted
    /// </param>    
    /// <param name="options" type="object">
    /// optional parameters.
    ///    offset: 6,
    ///    color: "black",
    ///    opacity: .25,
    ///    callback: null,
    ///    zIndex: 100,
    /// </param>    
    /// <returns type="jQuery" /> 
    if (typeof action == "object")
        options = action;

    var opt = { offset: 6,
        color: "black",
        opacity: 0.25,
        callback: null,
        zIndex: 100
    };
    $.extend(opt, options);

    this.each(function() {
        var el = $(this);
        var sh = $("#" + el.get(0).id + "Shadow");

        if (typeof action == "string") {
            if (action == "hide" || action == "remove") {
                el.unwatch("_shadowMove");
                sh.remove();
            }
            return;
        }

        var exists = true;
        if (sh.length < 1) {
            sh = $("<div style='height: 1px; width: 1px;'></div>")
                        .attr("id", el.get(0).id + "Shadow")
                        .insertAfter(el);

            var zi = el.css("zIndex");
            if (!zi || zi == "auto") {
                el.css("zIndex", opt.zIndex);
                sh.css("zIndex", opt.zIndex - 1);
            }

            var shEl = sh.get(0);
            if (typeof shEl.style.filter == "string") {
                shEl.style.filter = 'progid:DXImageTransform.Microsoft.Blur(makeShadow=1, shadowOpacity=' + opt.opacity.toString() + ', pixelRadius=3)';
                opt.offset = opt.offset - 4;
            }
            exists = false;
        }

        el.css("position", "absolute");
        var vis = el.is(":visible");
        if (!vis)
            el.show();  // must be visible to get .position

        var pos = el.position();

        sh.show()
          .css({ position: "absolute",
              width: el.outerWidth(),
              height: el.outerHeight(),
              opacity: opt.opacity,
              background: opt.color,
              left: pos.left + opt.offset,
              top: pos.top + opt.offset
          })
       .css("-moz-border-radius", "0px 1px 2px 1px")
       .css("-webkit-border-radius", "3px");

        if (!vis) {
            el.hide();
            sh.hide();
        }

        zIndex = el.css("zIndex");
        if (zIndex && zIndex != "auto")
            sh.css("zIndex", zIndex - 1);
        else {
            el.css("zIndex", opt.zIndex); sh.css("zIndex", opt.zIndex - 1);
        }

        if (!exists) {
//            el.watch("left,top,width,height,display,opacity,zIndex",
//                 function(w, i) {
//                     if (el.is(":visible")) {
//                         $(this).shadow(opt);
//                         sh.css("opacity", el.css("opacity") * opt.opacity);
//                     }
//                     else
//                         sh.hide();

//                 },
//                 100, "_shadowMove");
        }

        if (opt.callback)
            opt.callback(sh);
    });
    return this;
}

function _ModalDialog(sel, opt) {
    var _I = this;
    var jEl = $(sel);
    if (jEl.length < 1)
        jEl = $("#" + sel);

    this.overlayId = "_ModalOverlay";

    this.contentId = jEl.get(0).id;
    this.headerId = "";
    this.backgroundOpacity = .70;
    this.fadeInBackground = false;
    this.zIndex = 10000;
    this.jOverlay = null;
    this.keepCentered = true;
    this.dialogHandler = null;
    $.extend(_I, opt);
    var hideLists = null;

    this.show = function(msg, head, asHtml) {
        if (_I.contentId && typeof msg == "string")
            !asHtml ? $("#" + _I.contentId).text(msg) : $("#" + _I.contentId).html(msg);
        if (_I.headerId && typeof head == "string")
            !asHtml ? $("#" + _I.headerId).text(head) : $("#" + _I.headerId).html(head);

        jEl.css({ zIndex: _I.zIndex + 2 }).show().centerInClient();

        var bg = opaqueOverlay({ zIndex: _I.zIndex + 1, sel: "#" + _I.overlayId, opacity: _I.backgroundOpacity });

        _I.zIndex++;
        if (_I.fadeInBackground)
            bg.hide().fadeIn("slow");


        // *** track any clicks inside modal dialog
        jEl.click(_I.callback);

        if (_I.keepCentered)
            $(window).bind("resize.modal", function() { jEl.centerInClient() })
                         .bind("scroll.modal", function() { jEl.centerInClient() });

        // hide visible IE listboxes and store
        if ($.browser.msie && $.browser.version < "7")
            hideLists = $("select:visible").not($(jEl).find("select")).hide();
    }
    this.hide = function() {
        jEl.hide();
        if (_I.keepCentered)
            $(window).unbind("resize.modal")
                         .unbind("scroll.modal");
        opaqueOverlay("hide", { sel: "#" + _I.overlayId });
        jEl.unbind("click");

        // restore IE list boxes
        if (hideLists) {
            hideLists.show(); hideLists = null;
        }
    }
    this.genericDialog = function(msg, header, isHtml, handler) {
        var dl = $("#_MBOX");
        if (dl.length < 1) {
            var dl = $("<div></div>").addClass("blackBorder dragwindow").attr("id", "_MBOX").css({ width: 400 });
            var head = $("<div></div>").addClass("gridheader").attr("id", "_MBOXHEADER");
            var ctn = $("<div></div>").addClass("containercontent").attr("id", "_MBOXCONTENT");
            dl.append(head).append(ctn).appendTo(document.body);
        }
        dl.modalDialog({ dialogHandler: handler, headerId: "_MBOXHEADER", contentId: "_MBOXCONTENT" },
                          msg, header, isHtml)
          .draggable().shadow()
          .closable({ closeHandler: handler || function() { dl.modalDialog("hide"); } });
    }
    this.callback = function(e) {
        if (_I.dialogHandler) {
            var btn = (e.target == $("#" + _I.okButtonId).get(0)) ? 1 : 0;
            if (_I.dialogHandler.call(e.target, e, btn) == false)
                return;
            setTimeout(function() { _I.hide(); }, 10);
            return;
        }
        // by default close window when clicking a button or link
        if ($(e.target).is(":button,a,img"))
            setTimeout(function() { _I.hide(); }, 10);
    }
}
$.fn.modalDialog = function(opt, msg, head, asHtml, handler) {
    if (this.length < 1)
        return this;

    // only works with a single instance
    var el = this.get(0);
    var jEl = $(el);
    var dId = "modal" + el.id;

    var md = jEl.data(dId);
    if (!md)
        md = new _ModalDialog(jEl, opt);
    if (typeof opt == "string") {
        if (opt == "hide" || opt == "close")
            md.hide();
        if (opt == "instance" || opt == "get")
            return md;
        if (opt == "generic")
            md.genericDialog(msg, head, asHtml, handler);
        return;
    }
    md.show(msg, head, asHtml);
    jEl.data(dId, md);

    return this;
}
this.opaqueOverlay = function(opt, p2) {
    var _I = this;
    var jWin = $(window);

    this.sel = "#_ShadowOverlay";
    this.opacity = 0.75;
    this.zIndex = 10000;
    $.extend(this, p2 || opt);

    var sh = $(sel);
    if (opt == "hide") {
        if (sh.length < 1)
            return;
        sh.hide();
        sh.get(0).opaqueOverlay = false;
        jWin.unbind("resize.opaque").unbind("scroll.opaque");
        return;
    }

    if (sh.length < 1)
        sh = $("<div></div>")
                 .attr("id", this.sel.substr(1))
                 .css("background", "black")
                 .appendTo(document.body);

    var el = sh.get(0);
    sh.show();

    if (!el.opaqueOverlay)
        jWin.bind("resize.opaque", function() { opaqueOverlay(opt); })
            .bind("scroll.opaque", function() { opaqueOverlay(opt); });

    el.opaqueOverlay = true;

    sh.css({ top: 0 + jWin.scrollTop(), left: 0 + jWin.scrollLeft(), position: "absolute", opacity: _I.opacity, zIndex: _I.zIndex })
        .width(jWin.width())
        .height(jWin.height());
    return sh;
}


if (!$.fn.draggable) {
    $.fn.draggable = function(opt) {
        return this.each(function() {
            var el = $(this);
            var drag = el.data("draggable");

            if (typeof opt == "string") {
                if (drag && opt == "remove") {
                    drag.stopDragging();
                    el.removeData("draggable");
                }
                return;
            }
            if (!drag) {
                drag = new DragBehavior(this, opt);
                el.data("draggable", drag);
            }
        });
    }
    var __dragIndex = 1;

    function DragBehavior(sel, opt) {
        var _I = this;
        var el = $(sel);

        this.handle = "";
        this.opacity = 0.75;
        this.start = null;
        this.stop = null;
        this.dragDelay = 100;
        this.forceAbsolute = false;

        $.extend(_I, opt);

        _I.handle = _I.handle ? $(_I.handle) : el;
        if (_I.handle.length < 1)
            _I.handle = el;

        var isMouseDown = false;
        var isDrag = false;
        var timeMD = 0;
        var clicked = -1;
        var deltaX = 0;
        var deltaY = 0;
        var savedOpacity = 1;
        var savedzIndex = 0;

        this.mouseDown = function(e) {
            var dEl = _I.handle.get(0);
            var s = false;
            $(e.target).parents().each(function() { if (this == dEl) s = true; });
            if (isMouseDown || (e.target != dEl && !s) || $(e.target).is(".closebox,input,textara,a"))
                return;

            isMouseDown = true;
            isDrag = false;

            var pos = _I.handle.offset();
            deltaX = e.pageX - pos.left;
            deltaY = e.pageY - pos.top;

            setTimeout(function() {
                if (!isMouseDown) return;
                el.show().makeAbsolute(_I.forceAbsolute);
                _I.dragActivate(e);
            }, _I.dragDelay);

        }
        var nf = function(e) { e.stopPropagation(); };
        this.dragActivate = function(e) {
            if (!isMouseDown) return;
            isDrag = true;
            _I.moveToMouse(e);
            isMouseDown = true;
            savedzIndex = el.css("zIndex");
            el.css("zIndex", 150000);
            savedOpacity = el.css("opacity");
            el.css({ opacity: _I.opacity, cursor: "move" });

            $(document).bind("mousemove.dbh", _I.mouseMove);
            $(document.body).bind("selectstart.dbh", nf);
            $(document.body).bind("dragstart.dbh", nf);
            $(document.body).bind("selectstart.dbh", nf);
            _I.handle.bind("selectstart.dbh", nf);
            if (_I.start)
                _I.start(e, _I);
        }
        this.dragDeactivate = function(e, noMove) {
            if (!isMouseDown) return;
            isMouseDown = false;

            if (!isDrag) return;
            isDrag = false;

            if (!noMove)
                _I.moveToMouse(e);
            $(document).unbind("mousemove.dbh");

            $(document).unbind("selectstart.dbh");
            $(document.body).unbind("dragstart.dbh");
            $(document.body).unbind("selectstart.dbh");
            _I.handle.unbind("selectstart.dbh");

            if (!noMove) {
                __dragIndex += 10;
                el.css({ zIndex: 10000 + __dragIndex, cursor: "auto" });
                el.css("opacity", savedOpacity);
                if (_I.stop)
                    _I.stop(e, _I);
            }
        }
        this.mouseUp = function(e) {
            _I.dragDeactivate(e);
        }
        this.mouseMove = function(e) {
            if (isMouseDown)
                _I.moveToMouse(e);
        }
        this.moveToMouse = function(e) {
            el.css({ left: e.pageX - deltaX, top: e.pageY - deltaY });
        }
        this.stopDragging = function() {
            if (!isDrag) return;
            _I.dragDeactivate(null, true);
            $(document).unbind("mousedown", _I.mouseDown);
        }
        $(document).mousedown(_I.mouseDown);
        $(document).mouseup(_I.mouseUp);
    }
}

$.fn.centerInClient = function(options) {
    /// <summary>Centers the selected items in the browser window. Takes into account scroll position.
    /// Ideally the selected set should only match a single element.
    /// </summary>    
    /// <param name="fn" type="Function">Optional function called when centering is complete. Passed DOM element as parameter</param>    
    /// <param name="forceAbsolute" type="Boolean">if true forces the element to be removed from the document flow 
    ///  and attached to the body element to ensure proper absolute positioning. 
    /// Be aware that this may cause ID hierachy for CSS styles to be affected.
    /// </param>
    /// <returns type="jQuery" />
    var opt = { forceAbsolute: false,
        container: window,    // selector of element to center in
        completed: null
    };
    $.extend(opt, options);

    return this.each(function(i) {
        var el = $(this);
        var jWin = $(opt.container);
        var isWin = opt.container == window;

        // force to the top of document to ENSURE that 
        // document absolute positioning is available
        if (opt.forceAbsolute) {
            if (isWin)
                el.remove().appendTo("body");
            else
                el.remove().appendTo(jWin.get(0));
        }

        // have to make absolute
        el.css("position", "absolute");

        // height is off a bit so fudge it
        var heightFudge = 2.2;

        var x = (isWin ? jWin.width() : jWin.outerWidth()) / 2 - el.outerWidth() / 2;
        var y = (isWin ? jWin.height() : jWin.outerHeight()) / heightFudge - el.outerHeight() / 2;

        el.css({ left: x + jWin.scrollLeft(), top: y + jWin.scrollTop(), margin: 0 });

        var zi = el.css("zIndex");
        if (!zi || zi == "auto")
            el.css("zIndex", 1);

        // if specified make callback and pass element
        if (opt.completed)
            opt.completed(this);
    });
}

/*
* jQuery Tooltip plugin 1.3
*
* http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
* http://docs.jquery.com/Plugins/Tooltip
*
* Copyright (c) 2006 - 2008 JÃ¶rn Zaefferer
*
* $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
* 
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*/; (function($) {
    var helper = {}, current, title, tID, IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent), track = false; $.tooltip = { blocked: false, defaults: { delay: 200, fade: false, showURL: true, extraClass: "", top: 15, left: 15, id: "tooltip" }, block: function() { $.tooltip.blocked = !$.tooltip.blocked; } }; $.fn.extend({ tooltip: function(settings) { settings = $.extend({}, $.tooltip.defaults, settings); createHelper(settings); return this.each(function() { $.data(this, "tooltip", settings); this.tOpacity = helper.parent.css("opacity"); this.tooltipText = this.title; $(this).removeAttr("title"); this.alt = ""; }).mouseover(save).mouseout(hide).click(hide); }, fixPNG: IE ? function() { return this.each(function() { var image = $(this).css('backgroundImage'); if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) { image = RegExp.$1; $(this).css({ 'backgroundImage': 'none', 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" }).each(function() { var position = $(this).css('position'); if (position != 'absolute' && position != 'relative') $(this).css('position', 'relative'); }); } }); } : function() { return this; }, unfixPNG: IE ? function() { return this.each(function() { $(this).css({ 'filter': '', backgroundImage: '' }); }); } : function() { return this; }, hideWhenEmpty: function() { return this.each(function() { $(this)[$(this).html() ? "show" : "hide"](); }); }, url: function() { return this.attr('href') || this.attr('src'); } }); function createHelper(settings) { if (helper.parent) return; helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>').appendTo(document.body).hide(); if ($.fn.bgiframe) helper.parent.bgiframe(); helper.title = $('h3', helper.parent); helper.body = $('div.body', helper.parent); helper.url = $('div.url', helper.parent); } function settings(element) { return $.data(element, "tooltip"); } function handle(event) {
        if (settings(this).delay) tID = setTimeout(show, settings(this).delay); else
            show(); track = !!settings(this).track; $(document.body).bind('mousemove', update); update(event);
    } function save() {
        if ($.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler)) return; current = this; title = this.tooltipText; if (settings(this).bodyHandler) { helper.title.hide(); var bodyContent = settings(this).bodyHandler.call(this); if (bodyContent.nodeType || bodyContent.jquery) { helper.body.empty().append(bodyContent) } else { helper.body.html(bodyContent); } helper.body.show(); } else if (settings(this).showBody) { var parts = title.split(settings(this).showBody); helper.title.html(parts.shift()).show(); helper.body.empty(); for (var i = 0, part; (part = parts[i]); i++) { if (i > 0) helper.body.append("<br/>"); helper.body.append(part); } helper.body.hideWhenEmpty(); } else { helper.title.html(title).show(); helper.body.hide(); } if (settings(this).showURL && $(this).url()) helper.url.html($(this).url().replace('http://', '')).show(); else
            helper.url.hide(); helper.parent.addClass(settings(this).extraClass); if (settings(this).fixPNG) helper.parent.fixPNG(); handle.apply(this, arguments);
    } function show() {
        tID = null; if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
            if (helper.parent.is(":animated")) helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity); else
                helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
        } else { helper.parent.show(); } update();
    } function update(event) { if ($.tooltip.blocked) return; if (event && event.target.tagName == "OPTION") { return; } if (!track && helper.parent.is(":visible")) { $(document.body).unbind('mousemove', update) } if (current == null) { $(document.body).unbind('mousemove', update); return; } helper.parent.removeClass("viewport-right").removeClass("viewport-bottom"); var left = helper.parent[0].offsetLeft; var top = helper.parent[0].offsetTop; if (event) { left = event.pageX + settings(current).left; top = event.pageY + settings(current).top; var right = 'auto'; if (settings(current).positionLeft) { right = $(window).width() - left; left = 'auto'; } helper.parent.css({ left: left, right: right, top: top }); } var v = viewport(), h = helper.parent[0]; if (v.x + v.cx < h.offsetLeft + h.offsetWidth) { left -= h.offsetWidth + 20 + settings(current).left; helper.parent.css({ left: left + 'px' }).addClass("viewport-right"); } if (v.y + v.cy < h.offsetTop + h.offsetHeight) { top -= h.offsetHeight + 20 + settings(current).top; helper.parent.css({ top: top + 'px' }).addClass("viewport-bottom"); } } function viewport() { return { x: $(window).scrollLeft(), y: $(window).scrollTop(), cx: $(window).width(), cy: $(window).height() }; } function hide(event) {
        if ($.tooltip.blocked) return; if (tID) clearTimeout(tID); current = null; var tsettings = settings(this); function complete() { helper.parent.removeClass(tsettings.extraClass).hide().css("opacity", ""); } if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
            if (helper.parent.is(':animated')) helper.parent.stop().fadeTo(tsettings.fade, 0, complete); else
                helper.parent.stop().fadeOut(tsettings.fade, complete);
        } else
            complete(); if (settings(this).fixPNG) helper.parent.unfixPNG();
    } 
})(jQuery);
