(function ($) {

    $.fn.smContentSwap = function (options) {
      $.smContentSwap(this, options);
      return this;
    };

    $.smContentSwap = function (container, options) {
      var container = $(container).get(0);
      return container.smContentSwap || (container.smContentSwap = new $._smContentSwap(container, options));
    };

    $._smContentSwap = function (container, options) {
        this.container = $(container);
        this.options = $.extend(true, {}, this.defaultOptions, options);
        this.initialize();
    };

    $._smContentSwap.prototype = {
        requiredOptions: [
            'originalContent',
            'originalLink',
            'alternateContent',
            'alternateLink'
        ],
        defaultOptions: {
            originalContent: null,
            originalLink: null,
            onBeforeOriginalShow: null,
            onOriginalShow: null,
            alternateContent: null,
            alternateLink: null,
            onBeforeAlternateShow: null,
            onAlternateShow: null,
            autoHeight: true,
            autoWidth: true
        },
        contents: {},
        links: {},
        options: null,
        initialize: function () {
            var _this = this;
            $.each(this.requiredOptions, function (i, e) {
                if (!_this.options[e])
                    throw new Error('Required option ('+e+') not set.');
            });
            this.contents = {
                original: $(this.options.originalContent),
                alternate: $(this.options.alternateContent).hide()
            };
            this.links = {
                original: $(this.options.originalLink).click(function (e) { return _this.onOriginalLinkClick(e); }),
                alternate: $(this.options.alternateLink).click(function (e) { return _this.onAlternateLinkClick(e); })
            };
            this.contents.alternate.appendTo('body');
            /*
            if (this.options.autoHeight) {
                var hc = this.container.height(),
                    ho = this.contents.original.outerHeight(true),
                    ha = this.contents.alternate.show().outerHeight(true);
                this.contents.alternate.hide();
                this.container.css({ height: (ho > ha) ? hc + ho - ha : hc });
            }
            if (this.options.autoWidth) {
                this.contents.alternate.css({ width: this.contents.original.width() });
            }
            var o = this.contents.original.first().offset();
            this.contents.alternate.css({
                position: 'absolute',
                top: o.top,
                left: o.left,
                zIndex: 9999
            }).hide();
            */
            if (typeof this.options.onOriginalShow == 'function')
                this.options.onOriginalShow();
        },
        positionContainers: function () {
            var hide_original = this.contents.original.is(':hidden'),
                hide_alternate = this.contents.alternate.is(':hidden');
            if (this.options.autoHeight) {
                var hc = this.container.height(),
                    ho = this.contents.original.show().outerHeight(true),
                    ha = this.contents.alternate.show().outerHeight(true);
                if (hide_alternate)
                    this.contents.alternate.hide();
                if (ha > ho && ha > hc)
                    this.container.css({ minHeight: hc + ha - ho });
                else
                    this.container.css({ minHeight: hc });
                //this.container.css({ height: (ho > ha) ? hc + ho - ha : hc });
            }
            if (this.options.autoWidth) {
                this.contents.alternate.css({ width: this.contents.original.width() });
            }
            var o = this.contents.original.first().offset();
            if (hide_original)
                this.contents.original.hide();
            this.contents.alternate.css({
                position: 'absolute',
                top: o.top,
                left: o.left,
                zIndex: 5000
            });
            if (hide_alternate)
                this.contents.alternate.hide();
        },
        onOriginalLinkClick: function (e) {
            e.preventDefault();
            if ($.isFunction(this.options.onBeforeAlternateShow) && !this.options.onBeforeAlternateShow())
                return false;
            var _this = this;
            this.positionContainers();
            this.contents.original.fadeOut('fast', function () {
                _this.contents.alternate.fadeIn('fast');
            });
            if (typeof _this.options.onAlternateShow == 'function')
                _this.options.onAlternateShow();
            return false;
        },
        onAlternateLinkClick: function (e) {
            e.preventDefault();
            if ($.isFunction(this.options.onBeforeOriginalShow) && !this.options.onBeforeOriginalShow())
                return false;
            var _this = this;
            this.positionContainers();
            this.contents.alternate.fadeOut('fast', function () {
                _this.contents.original.fadeIn('fast');
            });
            if (typeof _this.options.onOriginalShow == 'function')
                _this.options.onOriginalShow();
            return false;
        }
    };


})(jQuery);

