;( function( $ ) {

    // static method
    $.compare = function()
    {
        return $( document ).data( "compare" );
    }

    //
    // plugin object
    //
    Compare.prototype =
    {
        init: function( options )
        {
            this.options = $.extend( {
                cookieArg: "compare"
            }, options );
            this.products = {};
            this.fetchProducts_();
        },
        apply : function( fn )
        {
            if ( typeof(fn) == 'function' )
            {
                for ( var i in this.products )
                {
                    fn.call( this, i, this.products[i] );
                }
            }
        },
        add : function( id, gid )
        {
            this.products[id] = gid;
            this.reset_();
            $( document ).trigger( 'comparechange' );
        },
        remove : function( id )
        {
            if ( this.exists_( id ) )
            {
                this.products[id] = null;
                try
                {
                    delete this.products[id];
                }
                catch ( e )
                { }
                this.reset_();
                $( document ).trigger( 'comparechange' );
            }
        },
        clear : function( gid )
        {
            if ( gid != undefined )
            {
                this.apply( function( k, v ) {
                    if ( v == gid )
                        this.remove( k );
                } );
            }
            else
            {
                this.products = {};
            }
            this.reset_();
            $( document ).trigger( 'comparechange' );
        },
        size : function()
        {
            var sz = 0;
            for ( var j in this.products )
            {
                ++sz;
            }
            return sz;
        },
        exists_ : function( id )
        {
            return this.products[id] != undefined;
        },
        reset_ : function()
        {
            if ( this.size() )
            {
                $.cookie( this.options.cookieArg, $.toJSON( this.products ), { path : '/' } );
            }
            else
            {
                $.cookie( this.options.cookieArg, null, { path : '/', expires : -1 } );
            }
        },
        fetchProducts_ : function()
        {
            var source = $.cookie( this.options.cookieArg );
            if ( source )
            {
                try
                {
                    var products = $.evalJSON( source );
                    for ( var i in products )
                    {
                        this.products[i] = products[i];
                    }
                }
                catch ( ex )
                {
//                    alert( ex.message );
                }
            }
        }
    };
    Compare.prototype.constructor = Compare;
    function Compare()
    {
        this.init.apply( this, arguments );
    }

    // plugin
    $.fn.compare = function( options )
    {
        // options section
        var defaultOptions =
        {
            cookieArg: 'compare'
        };
        options = $.extend( defaultOptions, options );

        if ( !$( document ).data( "compare" ) )
        {
            $( document ).data( "compare", new Compare( options ) )
        }
        return this;
    }

} )( jQuery );
