function initPagerFavorite() {
    mediator = new Mediator();
    $$('li.btnKeep').each(function (btn) {
        context = new Context(KeepState.getInstance(), btn, mediator);
        mediator.add(context);
        btn.observe('click', function (){
            this.request();
        }.bind(context));
    });

    $$('li.btnDelete').each(function (btn) {
        context = new Context(DeleteState.getInstance(), btn, mediator);
        mediator.add(context);
        btn.observe('click', function (){
            this.request();
        }.bind(context));
    });
}

Event.observe(window,"load",initDetailFavorite);

function initDetailFavorite() {
    mediator = new Mediator();
    $$('li.btnKeepFolder').each(function (btn) {
        context = new Context(KeepFolderState.getInstance(), btn, mediator);
        mediator.add(context);
        btn.observe('click', function (){ this.request(); }.bind(context));
    });

    $$('li.btnDeleteFolder').each(function (btn) {
        context = new Context(DeleteFolderState.getInstance(), btn, mediator);
        mediator.add(context);
        btn.observe('click', function (){ this.request(); }.bind(context));
    });
}

function getSingleton() {
    if (this.instance == undefined) {
        this.instance = new this();
    }
    return this.instance;
}

/*
 *
 */
var Mediator = Class.create({
    initialize: function () {
        this.contexts = [];
    },

    add: function(context) {
        this.contexts.push(context);
    },

    each: function (iterator) {
        this.contexts.each(iterator);
    }
});

/*
 *
 */
var Context = Class.create({
    initialize: function (state, btn, mediator) {
        this.state = state;
        this.btn = btn;
        this.mediator = mediator;
    },

    setState: function (state) {
        this.state = state;
    },

    request: function () {
        this.state.execute(this);
        this.state.handle(this);
    },

    getValue: function () {
        return this.btn.value;
    },

    updateButton: function (className, innerHtml) {
        this.btn.className = className;
        this.btn.children[0].innerHTML = innerHtml;
    },

    toString: function () {
        return this.btn.value + ' [' + this.state.toString() + ']';
    }
});

/*
 *
 */
var State = Class.create({
    initialize: function () {
        this.header = $$('#headerExam p strong');
    },

    execute: function (context) {
        throw new Error();
    },

    handle: function (context) {
        throw new Error();
    },

    onSuccess: function (context) {
        context.updateButton(this.changeClassName, this.innerHtml);
        alert(this.msg);
        this.getFavoriteCount();
    },

    getFavoriteCount: function () {
        new Ajax.Request(
            '/favorite/count',
            {
                method: 'get',
                onSuccess: function (request) {
                this.header[0].innerHTML = request.responseText;
                }.bind(this)
            }
        );
    }
});

/*
 *
 */
var KeepState = Class.create(State, {
    url: '/favorite/add',

    changeClassName: 'btnDelete',

    innerHtml: '検討中フォルダから削除<span></span>',

    msg: "検討中フォルダへの追加が完了いたしました。\r\n検討中フォルダへは、ページ最上部右のボタンを押してください。\r\n",

    handle: function (context) {
        context.setState(DeleteState.getInstance());
    },

    execute: function (context) {
        new Ajax.Request(
            this.url,
            {
                method: 'get',
                parameters: 'id='+context.getValue(),
                onSuccess: function () {
                    this.onSuccess(context);
                }.bind(this)
            }
        );
    },

    toString: function () {
        return 'keep';
    }
});

KeepState.getInstance = getSingleton;

/*
 *
 */
var DeleteState = Class.create(State, {

    url: '/favorite/remove',

    changeClassName: 'btnKeep',

    innerHtml: '検討中フォルダに追加<span></span>',

    msg: '検討中フォルダから削除しました。',

    handle: function (context) {
        context.setState(KeepState.getInstance());
    },

    execute: function (context) {
        new Ajax.Request(
            this.url,
            {
                method: 'get',
                parameters: 'id='+context.getValue(),
                onSuccess: function () {
                    this.onSuccess(context);
                }.bind(this)
            }
        );
    },

    toString: function () {
        return 'delete';
    }
});

DeleteState.getInstance = getSingleton;

/*
 *
 */
var KeepFolderState = Class.create(KeepState, {

    changeClassName: 'btnDeleteFolder',

    handle: function (context) {
        context.setState(DeleteFolderState.getInstance());
    },

    onSuccess: function (context) {
        $$('li.btnKeepFolder').each(function (target) {
            target.className = this.changeClassName;
            target.children[0].innerHTML = this.innerHtml;
        }.bind(this));
        context.mediator.each(function (other) {
            if (other != context) {
                other.state.handle(other);
            }
        });
        alert(this.msg);
        this.getFavoriteCount();
    },

    toString: function () {
        return 'keepFolder';
    }
});

KeepFolderState.getInstance = getSingleton;

/*
 *
 */
var DeleteFolderState = Class.create(DeleteState, {

    changeClassName: 'btnKeepFolder',

    handle: function (context) {
        context.setState(KeepFolderState.getInstance());
    },

    onSuccess: function (context) {
        $$('li.btnDeleteFolder').each(function (target) {
            target.className = this.changeClassName;
            target.children[0].innerHTML = this.innerHtml;
        }.bind(this));
        context.mediator.each(function (other) {
            if (other != context) {
                other.state.handle(other);
            }
        });
        alert(this.msg);
        this.getFavoriteCount();
    },

    toString: function () {
        return 'deleteFolder';
    }
});

DeleteFolderState.getInstance = getSingleton;
