/**
 * Parameter Class
 */

var Queryable = Class.create({
    toQuery: function () {
        throw new Error(this.kind + '#toQuery is not implement.');
    }
});

var PageNumber = Class.create({
    id: 'curPageNum',

    getPageNumber: function () {
        throw new Error('Not Implemented this method.');
    },

    getCurrentPageNumber: function () {
        return this.getInput().value;
    },

    getInput: function () {
        return $(id);
    },

    toQuery: function () {
        return 'page=' + this.getPageNumber();
    }
});

var PrevPageNumber = Class.create(PageNumber, {
    getPageNumber: function () {
        return this.getCurrentPageNumber() - 1;
    }
});

var NextPageNumber = Class.create(PageNumber, {
    getPageNumber: function () {
        return this.getCurrentPageNumber() + 1;
    }
});

var Parameter = Class.create(Queryable, {
    getName: function () {
        // you must implement this method !
    },

    getKind: function () {
        return this.kind;
    },

    getInput: function () {
        return this.input;
    },

    deleteInput: function () {
        this.input.parentNode.removeChild(this.input);
    },

    del: function () {
        this.deleteInput();
    },

    toQuery: function () {
        return this.input.name + '=' + this.input.value;
    },

    toString: function () {
        return this.getKind();
    }
});

/**
 * thickbox Option Class
 */
var ThickboxOption = Class.create(Parameter, {
    kind: 'option',

    initialize: function (input) {
        this.input      = input;
        input.className = this.kind;
    },

    getName: function () {
        return this.input.name;
    }
});

/**
 * Request Parameter Class
 */
var RequestParameter = Class.create(Parameter, {
    initialize: function (input, label) {
        this.input = input;
        this.label = label;

        this.input.id        = this.kind + '_' + this.input.value;
        this.input.name      = 'params[' + this.kind + '][]';
        this.input.className = this.kind + 'Ids';
        this.label.htmlFor   = this.kind + '_' + this.input.value;
    },

    getId: function () {
        return this.input.value;
    },

    getName: function () {
        return this.label.innerHTML;
    },

    getLabel: function () {
        return this.label;
    },

    deleteLabel: function () {
        this.label.parentNode.removeChild(this.label);
    },

    del: function () {
        this.deleteInput();
        this.deleteLabel();
    }
});

var Pref = Class.create(Parameter, {
    kind: 'pref',

    initialize: function (input, name) {
        this.input = input;
        this.name  = name;

        this.input.name      = 'params[' + this.kind + '][]';
        this.input.className = this.kind + 'Ids';
    },

    getId: function () {
        return this.input.value;
    },

    getName: function () {
        return this.name;
    }
});

var City = Class.create(RequestParameter, {
    kind: 'city'
});

var Line = Class.create(RequestParameter, {
    kind: 'line'
});

var Station = Class.create(RequestParameter, {
    kind: 'station'
});

var Job = Class.create(RequestParameter, {
    kind: 'job'
});

var Industry = Class.create(RequestParameter, {
    kind: 'industry'
});

var Environment = Class.create(RequestParameter, {
    kind: 'environment'
});

var Qualification = Class.create(RequestParameter, {
    kind: 'qualification'
});

var Experience = Class.create(RequestParameter, {
    kind: 'experience'
});

var Style = Class.create(RequestParameter, {
    kind: 'style'
});

/**
 * Convert to Query
 */
var QueryableManager = Class.create({
    toQuery: function () {
        throw new Error('Not Implement this method.');
    }
});

var PageNumberManager = Class.create(QueryableManager, {
    toQuery: function () {
        return this.pageNumber.toQuery();
    }
});

var PrevPageNumberManager = Class.create(PageNumberManager, {
    initialize: function () {
        this.pageNumber = new PrevPageNumber();
    }
});

var NextPageNumberManager = Class.create(PageNumberManager, {
    initialize: function () {
        this.pageNumber = new NextPageNumber();
    }
});

/**
 * Parameter Manager
 */
var ParameterManager = Class.create(QueryableManager, {
    params: [],

    initialize: function (factory, modal) {
        this.factory = factory;
        this.modal   = modal;
        this.initObj();
    },

    getKind: function () {
        return this.kind;
    },

    update: function () {
        // you need to implement this method.
    },

    initObj: function () {
    },

    toQuery: function () {
        return this.params.map(function (param) { return param.toQuery() }).join('&');
    },

    clear: function () {
        this.params.each(function (param) { param.del(); });
        this.params = [];
    }
});

/**
 * Thickbox Option Manager
 */
var ThickboxOptionManager = Class.create(ParameterManager, {
    kind: 'option',

    initObj: function () {
        this.params = $A(document.getElementsByClassName(this.kind)).map(function (input) {
            return new ThickboxOption(input);
        });
    }
});

/**
 * Request Parameter Manager
 */
var RequestParameterManager = Class.create(ParameterManager, {
    links: [],

    initObj: function () {
        this.nameList  = $(this.kind + 'NameList');
        this.idList    = $(this.kind + 'IdList');
        this.titleBox  = $(this.kind + 'BtnBox');
        this.detailBox = $(this.kind + 'Box');
        this.params    = $A(document.getElementsByClassName(this.kind + 'Ids')).map(function (input) {
            return new this.factory.klass(input, $('label_' + input.id));
        }.bind(this));
    },

    getIds: function () {
        return this.params.map(function (param) { return param.getId(); });
    },

    addParam: function (param) {
        isContained = this.params.find(function(p) {
            return (p.getId() == param.getId() && p.getName() == param.getName());
        }.bind(this));
        if (isContained == undefined) {
            this.idList.appendChild(param.getInput());
            this.idList.appendChild(param.getLabel());
            this.params.push(param);
            param.getInput().checked = true; // ie 6
        }
    },

    setParams: function (hash) {
        hash.each(function (pair) {
            this.addParam(this.factory.create(pair[0], pair[1]));
        }.bind(this));
    },

    active: function () {
        this.titleBox.className = 'BtnOnBox';
        jQuery(this.detailBox).fadeIn('slow');
    },

    inactive: function () {
        this.titleBox.className = 'BtnBox';
        jQuery(this.detailBox).fadeOut('slow');
    },

    update: function (hash) {
        if (!this.modified(hash)) {
            this.close();
            background.hide();
            return;
        }
        //this.clear();
        this.setParams(hash);
        this.doUpdate();
        this.active();
        this.close();
    },

    close: function () {
        this.modal.hide();
    },

    doUpdate: function () {
         // you needs to implement this method.
    },

    defaultCheck: function () {
        count = 0;
        this.getIds().each(function (id) {
            if ($(this.kind + '_input_' + id) != null) {
                $(this.kind + '_input_' + id).checked = true;
                count += 1;
            }
        }.bind(this));
        $A(document.getElementsByClassName('btnAdSearch')).each(function (btn) {
            btn.disabled = (count == 0);
        });
    },

    prev: function () {
    },

    next: function () {
    },

    modified: function (hash) {
        ids = [];
        if (hash == undefined) return;
        hash.each(function (pair) {
            ids.push(pair[0]);
        });
        if (ids.size() != this.getIds().size()) {
            return true;
        }
        return !$A(ids).all( function (item1) { return $A(this.getIds()).include(item1); }.bind(this));
    }
});

var PrefManager = Class.create(RequestParameterManager, {
    kind: 'pref',

    initObj: function () {
        this.nameList = $(this.kind + 'NameList');
        this.idList   = $(this.kind + 'IdList');
        this.params   = $A(document.getElementsByClassName(this.kind + 'Ids')).map(function (input) {
            return new Pref(input, $('prefNameList').innerHTML);
        });
    },

    getNames: function () {
        return this.params.map(function (param) { return param.getName(); });
    },

    setNameList: function (names) {
        this.nameList.innerHTML = names.join('/').truncate(16);
    },

    addParam: function (param) {
        this.idList.appendChild(param.getInput());
        for (var i = 0, len = this.params.length, name = param.getName(); i < len; i++) {
            if (this.params[i].getName() === name) {
                return;
            }
        }
        this.params.push(param);
    },

    active: function () {
    },

    inactive: function () {
    },

    doUpdate: function () {
        $('lineBtnBox').show();
        $('cityBtnBox').show();
        cityMgr.inactive();
        cityMgr.clear();
        lineMgr.inactive();
        lineMgr.clear();
        stationMgr.inactive();
        stationMgr.clear();
        this.setNameList(this.getNames());
    }
});

var CityManager = Class.create(RequestParameterManager, {
    kind: 'city',

    doUpdate: function () {
    /*
        lineMgr.inactive();
        lineMgr.clear();
        stationMgr.inactive();
        stationMgr.clear(); */
    }
});

var LineManager = Class.create(RequestParameterManager, {
    kind: 'line',

    links: ['lineSelect', 'changeLine'],

    update: function (hash) {
        this.tmp = hash;
        this.next();
    },

    change: function () {
        if (this.tmp) {
            this.setParams(this.tmp);
            this.active();
            $('lineRow').show(); // for IE
            this.close();
            this.tmp = undefined;
        }
    },

    doUpdate: function () {
        cityMgr.inactive();
        cityMgr.clear();
        stationMgr.inactive();
        stationMgr.clear();
    },

    active: function () {
        this.titleBox.className = 'BtnOnBox';
        jQuery(this.detailBox).fadeIn('slow');
        jQuery($('lineRow')).fadeIn('slow');
    },

    inactive: function () {
        this.titleBox.className = 'BtnBox';
        jQuery(this.detailBox).fadeOut('slow');
        jQuery($('lineRow')).fadeOut('slow');
    },

    next: function () {
        loadingAnimation.show();
        this.modal.hide();
        stationModalDialog.open('/dialog/station.htm?' + stationLinkMgr.getQuery());
    },

    close: function () {
        // do nothing.
    },

    toQuery: function () {
        if (this.tmp !== undefined) {
            return this.tmp.map(function (val) { return 'params[line][]=' + val[0]; }).join('&');
        } else {
            return this.params.map(function (param) { return param.toQuery() }).join('&');
        }
    }
});

var StationManager = Class.create(RequestParameterManager, {
    kind: 'station',

    initObj: function () {
        this.nameList  = $(this.kind + 'NameList');
        this.idList    = $(this.kind + 'IdList');
        this.params    = $A(document.getElementsByClassName(this.kind + 'Ids')).map(function (input) {
            return new this.factory.klass(input, $('label_' + input.id));
        }.bind(this));
    },

    doUpdate: function () {
    	lineMgr.clear();
    	lineMgr.active();
        $('lineRow').hide();
    	this.modal.hide();
    	this.active();
    	this.update();
    },

    active: function () {
        $('stationRow').show();
    },

    inactive: function () {
        $('stationRow').hide();
    },

    prev: function () {
        loadingAnimation.show();
        this.modal.hide();
        lineModalDialog.open('/dialog/line.htm?' + lineLinkMgr.getQuery());
    }
});

var SubRequestParameterManager = Class.create(RequestParameterManager, {
    active: function () {
        this.titleBox.className = 'on';
        jQuery(this.detailBox).fadeIn('slow');
    },

    inactive: function () {
        this.titleBox.className = 'on';
        jQuery(this.detailBox).fadeOut('slow');
    }
});

var JobManager = Class.create(SubRequestParameterManager, {
    kind: 'job'
});

var IndustryManager = Class.create(SubRequestParameterManager, {
    kind: 'industry'
});

var EnvironmentManager = Class.create(SubRequestParameterManager, {
    kind: 'environment'
});

var QualificationManager = Class.create(SubRequestParameterManager, {
    kind: 'qualification'
});

var ExperienceManager = Class.create(SubRequestParameterManager, {
    kind: 'experience'
});

var StyleManager = Class.create(SubRequestParameterManager, {
    kind: 'style'
});

/**
 * Parameter Factory Class
 */
var ParameterFactory = Class.create({
    initialize: function (klass) {
        this.klass = klass;
    },

    createInput: function (id, type) {
        var input = document.createElement('input');
        input.type    = type;
        input.checked = true;
        input.value   = id;
        return input;
    }
});

/**
 * Pref Factory Class
 */
var PrefFactory = Class.create(ParameterFactory, {
    initialize: function () {
        this.klass = Pref;
    },

    create: function (id, name) {
        var input = this.createInput(id, 'hidden');
        return new this.klass(input, name);
    }
});

/**
 * Thickbox Query Factory Class
 */
var ThickboxOptionFactory = Class.create(ParameterFactory, {
    initialize: function () {
        this.klass = ThickboxOption;
    },

    create: function (id, name) {
        var input = this.createInput(id, 'hidden');
        return new this.klass(input);
    }
});

/**
 * Parameter Factory Class
 */
var RequestParameterFactory = Class.create(ParameterFactory, {
    create: function (id, name) {
        var input = this.createInput(id, 'checkbox');
        var label = this.createLabel(id, name);
        return new this.klass(input, label);
    },

    createLabel: function (id, name) {
        var label = document.createElement('label');
        label.innerHTML = name;
        return label;
    }
});

var CityFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = City;
    }
});

var LineFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Line;
    }
});

var StationFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Station;
    }
});

var JobFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Job;
    }
});

var IndustryFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Industry;
    }
});

var EnvironmentFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Environment;
    }
});

var QualificationFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Qualification;
    }
});

var ExperienceFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Experience;
    }
});

var StyleFactory = Class.create(RequestParameterFactory, {
    initialize: function () {
        this.klass = Style;
    }
});

/**
 * Link Class
 */
var Link = Class.create({
    initialize: function (link, queryableMgrs) {
        this.link = link;
        this.queryableMgrs = queryableMgrs;
    },

    update: function () {
    	if (this.link != null) {
            this.link.search = '?' + this.queryableMgrs.map(function (queryable) { return queryable.toQuery(); }).join('&');
    	}
    }
});

var LinkManager = Class.create({
    initialize: function (queryableMgrs) {
        this.links = this.ids.map(function (id) { return new Link($(id), queryableMgrs); });
        this.queryableMgrs = queryableMgrs;
    },

    update: function () {
        this.links.each(function (link) { link.update(); });
    },

    getQuery: function () {
        return this.queryableMgrs.map(function (mgr) { return mgr.toQuery(); }).join('&');
    }
});

var PrefLinkManager = Class.create(LinkManager, {
    ids: ['prefSelect']
});

var CityLinkManager = Class.create(LinkManager, {
    ids: ['citySelect', 'changeCity']
});

var LineLinkManager = Class.create(LinkManager, {
    ids: ['lineSelect', 'changeLine']
});

var StationLinkManager = Class.create(LinkManager, {
    ids: ['changeStation']
});

var JobLinkManager = Class.create(LinkManager, {
    ids: ['jobSelect', 'changeJob']
});

var IndustryLinkManager = Class.create(LinkManager, {
    ids: ['industrySelect', 'changeIndustry']
});

var EnvironmentLinkManager = Class.create(LinkManager, {
    ids: ['environmentSelect', 'changeEnvironment']
});

var QualificationLinkManager = Class.create(LinkManager, {
    ids: ['qualificationSelect', 'changeQualification']
});

var ExperienceLinkManager = Class.create(LinkManager, {
    ids: ['experienceSelect', 'changeExperience']
});

var StyleLinkManager = Class.create(LinkManager, {
    ids: ['styleSelect', 'changeStyle']
});

var PageLinkManager = Class.create(LinkManager, {
    initialize: function (queryableMgrs) {
        this.queryableMgrs = queryableMgrs;
    },

    update: function () {
        this.getLinks().each(function (link) { link.update(); });
    },

    getLinks: function () {
        return $A(document.getElementsByClassName(this.className));
    },

    getCurrentPageNumber: function () {
        return $(this.currentPageNumId).value;
    }
});

var PrevLinkManager = Class.create(PageLinkManager, {
    className: 'prev'
});

var NextLinkManager = Class.create(PageLinkManager, {
    className: 'next'
});


/*
 * Recruitment Box Class
 */

var RecruitmentBox = Class.create({
    initialize: function (anchor, input) {
        this.anchor = anchor;
        this.input  = input;
        this.list   = anchor.parentNode;

        this.anchor.observe('click', this.click.bindAsEventListener(this));
    },

    click: function () {
        if (this.input.checked) {
            this.input.checked = false;
            this.list.className = this.list.className.replace(/ on/, '');
        } else {
            this.input.checked = true;
            this.list.className = this.list.className + ' on';
        }
    }
});


/**
 * Keyword Search
 */

var KeywordSearchButton = Class.create({
    initialize: function () {
        this.btn   = $('keywordSearchBtn');
        this.input = $('keywordInput');

        this.btn.observe('click', function () {
            if (this.input.value == '') {
                alert('キーワードを入力してください');
            }
        }.bindAsEventListener(this));
    }
});

/**
 * Salary Select
 */
var SalarySelect = Class.create({
    initialize: function () {
        this.select = $('salaryDivision');
        $('salaryDivision').observe('change', this.change.bindAsEventListener(this));
    },
    change: function () {
        var salary = $('salary');
        var range = null;
        switch (this.select.options[this.select.selectedIndex].value) {
            case '1':
                var range = [750, 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, 1600, 1700, 1800, 1900, 2000, 2200, 2400, 2600, 2800, 3000];
                break;
            case '2':
                var range = [3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000, 16000, 18000, 20000, 30000, 40000, 50000];
                break;
            case '3':
                var range = [100000, 150000, 200000, 250000, 300000, 350000, 400000];
                break;
            case '4':
                var range = [1200000, 1600000, 2000000, 2400000, 2800000, 3200000, 3600000, 4000000, 4400000, 4800000, 5200000, 5600000, 6000000];
                break;
            default:
                var range = [];
                break;
        }
        var index = 0;
        salary.options.length = 0;
        salary.options[index++] = new Option(
            '問わない',
            '0',
            false,
            false
        );
        for (var i = 0, len = range.length; i < len; i++) {
            salary.options[index++] = new Option(
                this.format(range[i]),
                range[i],
                false,
                false
            );
        }
    },
    format: function (number) {
        var str = number + '';
        var idx = str.length;
        var end = str.length;
        var result = '';
        while (idx--) {
            if (str.substring(idx, end).length === 3) {
                result = str.substring(idx, end) + (result ? ',' : '') + result;
                end = idx;
            }
        }
        var left = str.substring(0, end);
        result = left ? left + ',' + result : result;
        return result;
    }
});
