function setup(params) {
    function shopEffect() {
        var scrollable = $('ScrollWrapper');
        var left = $('GoLeft');
        var right = $('GoRight');
        var images = $$('.PhotoList li');

        var effect;

        function move(options) {
            options.duration = Math.abs(options.x) / 80.0;
            effect = new Effect.Move(scrollable, options);
        }

        function scrollableWidth() {
            var width = 0;
            for (var i = 0; i < images.length; i++) {
                width += images[i].getWidth();
            }
            return width;
        }

        function moveLeft() {
            var offset = right.positionedOffset()[0] - (scrollableWidth() + scrollable.positionedOffset()[0]);
            move({x: offset});
        }

        function moveRight() {
            var offset = left.getWidth() - scrollable.positionedOffset()[0];
            move({x: offset});
        }

        function cancel() {
            if (effect) {
                effect.cancel();
                effect = null;
            }
        }

        function setup() {
            if (left && images.length >= 4) {
                left.observe('mouseover', moveRight);
                left.observe('mouseout', cancel);
                right.observe('mouseover', moveLeft);
                right.observe('mouseout', cancel);
            }
            
        }

        return {
            setup: setup
        };
    }

    function dialog() {
        function sendClickLog(key){
            var url = "/log/" + key + "/" + params.shopId;
            new Ajax.Request( url , {
                method:  'get',
                onSuccess:  function(transport) {} // do nothing
            });
        }

        function openDialog(name, value, options) {
            options = options || {};
            options.height = options.height || 130;
            options.width = options.width || 350;
            options.showProgress = true;
            options.okLabel = 'OK';
            Dialog.alert("<div><div class='DialogHead'><p class='Name'>" + name + "</p></div><div class='DialogBody'><p class='Nakami'>" + value + "</p></div></div>", options);
        }

        function decrypted_email(args) {
            return args.reverse().join('');
        }

        function addOpenDialogEvent(id, name, logkey, value, options) {
            var e = $(id);
            if (e) {
                e.observe('click', function () {
                    sendClickLog(logkey);
                    openDialog(name, value, options);
                    return false;
                });
            }
        }

        function setup() {
            addOpenDialogEvent('openTel', '電話番号', 'tel', params.tel);
            addOpenDialogEvent('openFax', 'FAX', 'fax', params.fax);
            addOpenDialogEvent('openEmail', 'email', 'email', decrypted_email(params.encryptedEmail));
            addOpenDialogEvent('openBankAccount', '振込先', 'bank', params.bankAccount, {height: 180});
        }

        return {
            setup: setup
        };
    }

    function map() {
        function setup() {
            if (params.hasCoordinate) {
                googleMap({smallControl: true});
            }
        }

        return {
            setup: setup
        };
    }

    function image() {
        function swapImage( image_id ) {
            var id_to_url = image_id.toString().split('').reverse().join('/');
            var img = $('shop_image_' + image_id);
            var main = $('main_image');
            main.src = "/file/shop_image/" + id_to_url + "/w358h258.jpg";
            var main_anchor = $('main_image_anchor');
            main_anchor.href = "/file/shop_image/" + id_to_url + "/w600h600.jpg";
            changeNowViewing(img);
        }

        function changeNowViewing(nowImg) {
            var old = $$('li.NowView')[0];
            if (old) {
                old.removeClassName('NowView');
            }
            $(nowImg.parentNode).addClassName('NowView');
        }

        function openImage( href ) {
            // アクセスカウンタ用にリクエストを投げる
            new Ajax.Request('/shop/image/' + params.shopId, {
                method: 'get',
                asynchronous: true
            });
            window.open(href);
            return false;
        }

        function setup() {
            window.swapImage = swapImage;
            window.openImage = openImage;
        }

        return {
            setup: setup
        };
    }

    document.observe('dom:loaded', function () {
        shopEffect().setup();
        dialog().setup();
        image().setup();
    });
    // 内部で使用しているメソッドが dom:loaded でイベント実行している
    map().setup();
}
