(function(){
    'use strict';

    var suggest = {
        config: {
            url: '/suggest/',
            suggest_box_margin_bottom: 2,
            search_threshold: 0
        },
        category: {
            'DOH': ['COM', 'MNG', 'ICG', 'INV', 'NRE', 'ET3'],
            'SOF': ['MDC', 'ICG', 'IN2', 'NR2', 'MOV', 'TOL', 'SOU', 'MUS', 'ET4'],
            'GAM': ['ACN', 'ADV', 'DNV', 'GAE', 'PZL', 'QIZ', 'RPG', 'SLN', 'STG', 'TBL', 'TYP']
        },
        $form: null,
        $input: null,
        $box: null,
        $site_category: null,
        $age_category: null,
        is_touch: false,
        is_female: false,
        touch_max_show_work: 3,
        site_id: 'general-jp',
        lang: 'jp',
        last_val: '',
        request_time: 0,
        timer: null
    };

    suggest.i18n = {
        'jp': {
            'work_name': '作品',
            'maker_name': 'サークル/ブランド',
            'more': '「%s」でキーワード検索する',
            'more_count': '%s件の候補を表示中',
            'ADL': '18禁',
            'DOH': '同人誌',
            'SOF': '同人ソフト',
            'GAM': '同人ゲーム',
            'SOU': '音声作品',
            'MNG': 'マンガ',
            'COM': 'マンガ',
            'MDC': 'デジタルコミック',
            'SCM': '劇画',
            'ET4': 'その他同人ソフト',
            'ET3': 'その他同人誌',
            'PZL': 'パズル',
            'ACN': 'アクション',
            'QIZ': 'クイズ',
            'RPG': 'ロールプレイング',
            'SLN': 'シミュレーション',
            'STG': 'シューティング',
            'TBL': 'テーブルゲーム',
            'TYP': 'タイピング',
            'ADV': 'アドベンチャー',
            'DNV': 'デジタルノベル',
            'ETC': 'その他ゲーム',
            'GSH': '画集',
            'IST': 'イラスト集',
            'ICG': 'イラスト集(CG集)',
            'IN2': 'イラスト(CG)+ノベル',
            'INV': 'イラスト+ノベル',
            'MOV': '動画作品',
            'MUS': '音楽作品',
            'NRE': '同人誌ノベル',
            'NR2': '同人ソフトノベル',
            'PHT': '写真集',
            'TOL': 'ツール/アクセサリ',
            'MTR': '素材'
        },
        'en': {
            'work_name': 'Title',
            'maker_name': 'Circle/Brand',
            'more': 'See more results',
            'more_count': 'Displaying top %s results',
            'ADL': 'R18++',
            'DOH': 'Doujinsji',
            'SOF': 'Software',
            'GAM': 'Game',
            'SOU': 'Audio',
            'MNG': 'Manga (PDF)',
            'MDC': 'Manga',
            'ET3': 'Others (PDF)',
            'ET4': 'Others (Non-PDF)',
            'ACN': 'Action',
            'PZL': 'Puzzle',
            'QIZ': 'Quiz',
            'RPG': 'Role-Playing',
            'SLN': 'Simulation',
            'STG': 'Shooter',
            'TBL': 'Card & Block Breaking',
            'TYP': 'Typing',
            'ADV': 'Adventure',
            'DNV': 'Digital Novel',
            'ETC': 'Others (Game)',
            'IST': 'Illustration (PDF)',
            'ICG': 'CG Collection',
            'IN2': 'CG+Novel',
            'INV': 'Illustration+Novel (PDF)',
            'MOV': 'Animation',
            'MUS': 'Music',
            'NRE': 'Novel (PDF)',
            'NR2': 'Novel',
            'TOL': 'Utility / Tool',
            'MTR': 'Materials'
        }
    };

    suggest.init = function() {
        // SSLページでは使わない
        if(location.protocol === 'https:') {
            return false;
        }

        suggest.is_touch = (/touch$/.test(getSiteName()));
        suggest.is_female = $.isFemaleSite();
        suggest.lang = getSiteLang();

        if(suggest.is_touch) {
            suggest.$input = $('#fs_search input[name="keyword"]');
            suggest.$site_category = $('#form_work_category');
            suggest.$age_category = $('#form_age_category');
        } else {
            suggest.$input = $('#search_text');
            suggest.$site_category = $('[name=site_category]');
        }

        suggest.$form = suggest.$input.parents('form');

        if(suggest.$form.length === 0 || suggest.$input.length === 0) {
            return false;
        }

        suggest.$box = $('<ul class="suggest'+(suggest.is_touch ? ' touch' : '')+(suggest.is_female ? ' girls' : '')+($.getSiteAgeCategory() === 'adult' && getSiteLang() === 'en' ? ' ecchi-eng' : '')+'"></ul>');
        suggest.last_val = suggest.$input.val();

        if(location.host !== 'www.dlsite.com' && location.host !== 'www.origin.dlsite.com') {
            suggest.config.url = suggest.config.url.replace('//suggest', '//suggest.dev');
        }

        $('body').append(suggest.$box);

        return true;
    };

    suggest.setEvent = {
        suggest: function(){
            suggest.$form.bind({
                submit: function(){
                    suggest.controller.hideSuggest();
                }
            });

            suggest.$input.bind({
                keydown: function(e){
                    if(e.keyCode === 40 || e.keyCode === 9) {
                        suggest.controller.selectActive('down');
                        return false;
                    } else if(e.keyCode === 38) {
                        suggest.controller.selectActive('up');
                        return false;
                    } else if(e.keyCode === 13) {
                        var active = suggest.controller.enter();
                        if(active) {
                            return false;
                        }
                    } else if(e.keyCode === 27) {
                        suggest.controller.hideSuggest(false);
                        return true;
                    }
                },
                keyup: function(e){
                    var val = suggest.$input.val();

                    if(val === suggest.last_val) return;
                    suggest.last_val = val;

                    if(val.length < 2) {
                        suggest.controller.hideSuggest(false);
                        return;
                    }
                    if(/[ａ-ｚ]/.test(val)) return;

                    clearTimeout(suggest.timer);
                    suggest.request_time = Number(new Date());

                    suggest.timer = setTimeout(function(){
                        $.ajax({
                            url: suggest.config.url,
                            data: {
                                term: val,
                                site: suggest.site_id,
                                time: suggest.request_time,
                                touch: (suggest.is_touch ? 1 : 0)
                            },
                            dataType: 'jsonp',
                            success: function(json){
                                if(!json.work) return;
                                if(json.reqtime >= suggest.request_time) {
                                    suggest.controller.showSuggest(json);
                                }
                            }
                        });
                    }, suggest.config.search_threshold);
                },
                blur: function(){
                    suggest.controller.hideSuggest();
                }
            });

            suggest.$input.one('keyup', function(){
                if(typeof _gaq === 'object') {
                    _gaq.push(['_trackEvent', getSiteName(), 'suggest', 'launch', , true]);
                }
                if(typeof ga === 'function') {
                    ga('send', 'event', getSiteName(), 'suggest', 'launch', null);
                }
            });
        },
        boxPosition: function(){
            if(suggest.is_touch) {
                suggest.$input.bind('focus', function(){
                    var pos = suggest.$form.position();
                    if(pos !== undefined) {
                        $('html, body').animate({
                            scrollTop: pos.top
                        }, '300', 'swing');
                    }

                    pos = suggest.$input.offset();
                    suggest.$box.css({
                        top: pos.top + suggest.$input.outerHeight() + suggest.config.suggest_box_margin_bottom,
                        left: pos.left,
                        width: suggest.$input.outerWidth() - 2
                    });
                });
            }

            $(window).bind('resize', function(){
                var pos = suggest.$input.offset();
                suggest.$box.css({
                    top: pos.top + suggest.$input.outerHeight() + suggest.config.suggest_box_margin_bottom,
                    left: pos.left
                });
            }).triggerHandler('resize');
        },
        changeSiteId: function(){
            suggest.$site_category.bind('change', function(){
                suggest.site_id = suggest.util.getsite();
            });

            if(suggest.is_touch && suggest.$age_category.length !== 0) {
                suggest.$age_category.bind('change', function(){
                    suggest.site_id = suggest.util.getsite();
                });
            }

            suggest.site_id = suggest.util.getsite();
        }
    };

    suggest.controller = {
        showSuggest: function(json){
            if(json.work.length === 0 && json.maker.length === 0) {
                suggest.controller.hideSuggest(false);
                return;
            }

            var dom = '';

            if(suggest.is_touch) {
                dom = suggest.util.getWorkTouchDom(json.work);
            } else {
                var work_dom = suggest.util.getWorkDom(json.work);
                var maker_dom = suggest.util.getMakerDom(json.maker);
                var more_dom = suggest.util.getMoreDom(json);
                dom = work_dom + maker_dom + more_dom;
            }

            if(dom === '') {
                suggest.controller.hideSuggest(false);
                return;
            }

            suggest.$box.empty().append(dom).show();

            suggest.$box.find('.suggest-mini-icon img').bind('error', function(){
                if(/RJ[0-9]+/.test($(this).attr('src'))) {
                    $(this).attr('src', $(this).attr('src').replace(/RJ/ig, 'RE'));
                } else {
                    $(this).attr('src', '/images/web/home/no_img_mini.gif');
                }
            });

            suggest.$box.find('.suggest-item').bind('click', function(){
                var type = $(this).attr('data-type');
                if(typeof _gaq === 'object') {
                    _gaq.push(['_trackEvent', getSiteName(), 'suggest', 'enter_'+type+'_page', , true]);
                }
                if(typeof ga === 'function') {
                    ga('send', 'event', getSiteName(), 'suggest', 'enter_'+type+'_page', null);
                }
            });

            if(suggest.is_touch) {
                suggest.$box.find('.suggest-item').bind('touchstart', function(){
                    suggest.controller.selectActive($(this));
                }).bind('touchend', function(){
                    suggest.controller.selectActive();
                });
            } else {
                suggest.$box.find('.suggest-item').bind('mouseover', function(){
                    suggest.controller.selectActive($(this));
                });
            }
            suggest.$box.find('.suggest-more a').bind('click', function(){
                suggest.$form.trigger('submit');
                return false;
            });
        },
        hideSuggest: function(delay){
            delay = (delay === undefined ? true : delay);
            clearTimeout(suggest.timer);

            suggest.timer = setTimeout(function(){
                suggest.$box.empty().hide();
            }, delay ? 300 : 0);
        },
        selectActive: function(mixed){
            var $active = suggest.$box.find('.suggest-active');
            var $item = suggest.$box.find('.suggest-item');
            $item.removeClass('suggest-active');

            if(mixed === 'up') {
                if($active.length === 0) {
                    $item.last().addClass('suggest-active');
                } else {
                    var $prev = $active.prevAll('.suggest-item').eq(0);

                    if($prev.length === 0) {
                        $item.last().addClass('suggest-active');
                    } else {
                        $prev.addClass('suggest-active');
                    }
                }
            } else if(mixed === 'down') {
                if($active.length === 0) {
                    $item.first().addClass('suggest-active');
                } else {
                    var $next = $active.nextAll('.suggest-item').eq(0);

                    if($next.length === 0) {
                        $item.first().addClass('suggest-active');
                    } else {
                        $next.addClass('suggest-active');
                    }
                }
            } else if(typeof mixed === 'object') {
                mixed.addClass('suggest-active');
            }
        },
        enter: function(){
            var $active = suggest.$box.find('.suggest-active');

            if($active.hasClass('suggest-more')) {
                suggest.$form.trigger('submit');
                return false;
            }

            if($active.length !== 0) {
                var link = $active.find('a').attr('href');
                if(link !== '' && link !== undefined) {
                    var type = $active.attr('data-type');
                    if(typeof _gaq === 'object') {
                        _gaq.push(['_trackEvent', getSiteName(), 'suggest', 'enter_'+type+'_page', , true]);
                    }
                    if(typeof ga === 'function') {
                        ga('send', 'event', getSiteName(), 'suggest', 'enter_' + type + '_page', null);
                    }
                    location.href = link;
                    return true;
                }
            }

            return false;
        }
    };

    suggest.util = {
        getI18n: function(msg, arg){
            var l = suggest.i18n[suggest.lang][msg];
                if(typeof l === 'string') {
                    if($.isArray(arg)) {
                        for(var i=0;i<arg.length;i++) {
                            l = l.replace('%s', arg[i]);
                        }
                    }
                    return l;
                }
            return '';
        },
        getsite: function(){
            var site_id = '';

            if(suggest.$site_category.length !== 0) {
                if(suggest.$site_category.attr('checked') !== undefined) {
                    site_id = suggest.$site_category.filter(':checked').val();
                } else {
                    site_id = suggest.$site_category.find('option:selected:eq(0)').val();
                }

                if(suggest.is_touch && suggest.$age_category.length !== 0) {
                    var age = suggest.$age_category.find('option:selected:eq(0)').val();

                    if(age !== undefined && age !== '') {
                        site_id = age+'-'+site_id;
                    }

                    if(suggest.is_female) {
                        site_id = 'female-'+site_id;
                    }

                    if(age === undefined || age === '') {
                        site_id = 'all-'+site_id;
                    }
                }
            }

            if(site_id !== '') {
                return site_id;
            } else {
                if(suggest.is_female) {
                    return 'female';
                } else {
                    if(location.pathname.indexOf('ecchi-eng/girls') !== -1) {
                        return 'girlseng';
                    } else {
                        return $.getSiteAgeCategory()+'-'+getSiteLang();
                    }
                }
            }
        },
        dirname: function(workno){
            var prefix = workno.substring(0, 2);
            var id = workno.replace(prefix, '');
            id = Number(id);
            id = Math.ceil(id/1000)*1000;
            prefix = (prefix === 'RE' ? 'RJ': prefix);
            return prefix+('000000'+id).slice(-6);
        },
        siteid: function(workno){
            var prefix = workno.charAt(0);
            if(prefix === 'V') return 'professional';
            if(prefix === 'B') return 'books';
            return 'doujin';
        },
        siteurl: function(workno, age){
            var prefix = workno.substring(0, 2);
            var touch = (suggest.is_touch ? '-touch' : '');

            if(suggest.is_female) {
                if(prefix === 'BJ') return 'girls-pro' + touch;
                return 'girls' + touch;
            }

            if(age === 'adult') {
                if(prefix === 'VJ') return 'pro' + touch;
                if(prefix === 'BJ') return 'books' + touch;
                if(prefix === 'RE') return 'ecchi-eng' + touch;
                return 'maniax' + touch;
            } else {
                if(prefix === 'VJ') return 'soft' + touch;
                if(prefix === 'BJ') return 'comic' + touch;
                if(prefix === 'RE') return 'eng' + touch;
                return 'home' + touch;
            }
        },
        getCategory: function(genre){
            for(var i in suggest.category) {
                if($.inArray(genre, suggest.category[i]) !== -1) return i;
            }
            return '';
        },
        getWorkDom: function(work){
            if(work.length === 0) return '';

            var dom = '<div class="suggest-head">'+__('work_name')+'</div>';

            for(var i=0;i<work.length;i++) {
                var dirname = suggest.util.dirname(work[i].workno);
                var siteurl = suggest.util.siteurl(work[i].workno, work[i].age_category);
                var siteid = suggest.util.siteid(work[i].workno);
                var workno = work[i].workno.replace(/RE/ig, 'RJ');
                var imagedir = work[i].is_ana ? 'ana' : 'work';
                var workdir = work[i].is_ana ? 'announce' : 'work';
                var work_type = work[i].workno.charAt(0) === 'R' ? suggest.util.getCategory(work[i].work_type) : '';
                dom += '<li class="suggest-item" data-type="work">';
                dom += '<a href="/'+siteurl+'/'+workdir+'/=/product_id/'+work[i].workno+'.html">';
                dom += '<div class="suggest-mini-icon"><img src="//img.dlsite.jp/modpub/images2/'+imagedir+'/'+siteid+'/'+dirname+'/'+workno+(work[i].is_ana ? '_ana' : '')+'_img_mini.jpg"></div>';
                dom += '<div class="suggest-description">';
                dom += '<div class="suggest-title suggest-ellipsis">'+work[i].work_name+'</div>';
                dom += '<div class="suggest-name suggest-ellipsis">'+work[i].maker_name+'</div>';
                dom += '<div class="suggest-intro suggest-ellipsis">'+work[i].intro_s+'</div>';
                dom += '<div class="work_genre">';
                if(work[i].age_category === 'adult') {
                    dom += '<span class="icon_ADL">'+__('ADL')+'</span> ';
                }
                if(work_type !== '') {
                    dom += '<span class="icon_'+work_type+'">'+__(work_type)+'</span> ';
                }
                dom += '<span class="icon_'+work[i].work_type+'">'+__(work[i].work_type)+'</span></div>';
                dom += '</div>';
                dom += '</a>';
                dom += '</li>';
            }

            return dom;
        },
        getMakerDom: function(maker){
            if(maker.length === 0) return '';

            var dom = '<div class="suggest-head">'+__('maker_name')+'</div>';

            for(var i=0;i<maker.length;i++) {
                var dirname = suggest.util.dirname(maker[i].workno);
                var siteurl = $.getSiteName();
                var siteid = suggest.util.siteid(maker[i].workno);
                var workno = maker[i].workno.replace(/RE/ig, 'RJ');
                dom += '<li class="suggest-item" data-type="maker">';
                dom += '<a href="/'+siteurl+'/circle/profile/=/maker_id/'+maker[i].maker_id+'.html">';
                dom += '<div class="suggest-mini-icon"><img src="//img.dlsite.jp/modpub/images2/work/'+siteid+'/'+dirname+'/'+workno+'_img_mini.jpg"></div>';
                dom += '<div class="suggest-description">';
                dom += '<div class="suggest-title suggest-ellipsis">'+maker[i].maker_name+'</div>';
                if(suggest.lang === 'jp')
                {
                    dom += '<div class="suggest-name suggest-ellipsis">'+maker[i].maker_name_kana+'</div>';
                }
                dom += '</div>';
                dom += '</a>';
                dom += '</li>';

            }

            return dom;
        },
        getMoreDom: function(json){
            var count = json.work.length + json.maker.length;
            var keyword = $.trim(suggest.last_val);
            var dom = '<div class="suggest-item suggest-more"><a href="#">'+__('more', [keyword])+'<br><span>'+__('more_count', [count])+'</span></a></div>';
            return dom;
        },
        getWorkTouchDom: function(work){
            if(work.length === 0) return '';

            var dom = '';

            for(var i=0;i<work.length;i++) {
                if(i >= suggest.touch_max_show_work) break;

                var dirname = suggest.util.dirname(work[i].workno);
                var siteurl = suggest.util.siteurl(work[i].workno, work[i].age_category);
                var siteid = suggest.util.siteid(work[i].workno);
                var workdir = work[i].is_ana ? 'announce' : 'work';
                dom += '<li class="suggest-item" data-type="work">';
                dom += '<a href="/'+siteurl+'/'+workdir+'/=/product_id/'+work[i].workno+'.html">';
                dom += '<div class="suggest-description">';
                dom += '<div class="suggest-title suggest-ellipsis">'+work[i].work_name+'</div>';
                dom += '<div class="suggest-name suggest-ellipsis">'+work[i].maker_name+'</div>';
                dom += '</div>';
                dom += '</a>';
                dom += '</li>';
            }

            return dom;
        }
    };

    function __(msg, arg) {
        return suggest.util.getI18n(msg, arg);
    }

    $(function(){
        var init = suggest.init();

        if(init === false) return;

        suggest.setEvent.changeSiteId();
        suggest.setEvent.boxPosition();
        suggest.setEvent.suggest();
    });

})();
