function attachHandlersFor(controller, action, args) {
    var page = controller + '/' + action;

    switch(page) {
        case 'home/index':
            $$('#hello img').each(function(img) {
                img.observe('click', function(evt) {
                    var new_path = hello_pics[Math.floor(Math.random() * hello_pics.length)];
                    var new_title = new_path.split('/').pop().split('.').slice(0, -1).join('.').replace(/_/g, ' ');
                    $(this).src = new_path;
                    $(this).title = new_title;
                });
            });
            handleSwapVideos(413, 340);
            handleSwapPhotos('');
            break;
            
        case 'home/hello':
            $('show_tell_friends').observe('click', showDiv);
            clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing($$('#tell_friends textarea')[0]);
            break;
        
        case 'home/topics':
            $('show_add_talk').observe('click', showDiv);
            clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing($$('#add_talk input[type="text"]')[0]);
            clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing($$('#add_talk textarea')[0]);
            break;
        
        case 'home/photos':
            handleSwapPhotos('b');
            Event.observe(document, 'keypress', handleArrowKeysChangePhoto);
            $('show_instructions').observe('click', showDiv);
            $$('#instructions input')[0].observe('click', function(event) {
                $(this).activate();
            });
            break;
            
        case 'home/videos':
            if ($('you_tube_video_video_id')) {
            	$('you_tube_video_video_id').observe('change', function(event) {
            	    Event.stop(event);
            	    var videoId = this.value;
                    changeYouTubeVideo(videoId, 850, 700);
            	    return false;
            	});
            }
            handleSwapVideos(850, 700);
            
            $('show_instructions').observe('click', showDiv);
            $$('#instructions input')[0].observe('click', function(event) {
                $(this).activate();
            });
            
            break;
            
        case 'home/album': 
            $('show_tell_friends').observe('click', showDiv);
            clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing($$('#tell_friends textarea')[0]);
            break;
        
        case 'home/show':
        case 'admin/show':
        case 'admin/shows':
            handleShowShowDetails($$('.show_details'));
            break;
            
        case 'home/shows':
            handleShowShowDetails($$('.show_details'));
            $('show_past_shows').observe('click', function(event) {
                Event.stop(event);
                var url = '/load_past_shows';
                var params = {};
                $(this).addClassName('hidden');
                $('past_shows').removeClassName('hidden');
                doAjax(url, params);
    	        return false;
    	    });
	        break;
            
        case 'account/login':
            $$('form#login_in_body input').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
            
        case 'account/signup':
            $$('form#signup_in_body input').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
            
        case 'account/forgot_password':
            $$('form#forgot_password input').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
            
        case 'account/activate':
            $$('form#activate input').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
            
        case 'account/reset_password':
            $$('form#reset_password input').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
            
        case 'member/profile_photos':
            break;
            
        case 'admin/videos':
            $$('.video_status .selectable').each(function(selectable) {
                var videoId = $(selectable).up('li.video').id;
                var attributeName = 'media_status';
                var updateUrl = '/admin/update_video';
                handleSelectable(selectable, videoId, attributeName, updateUrl);
            });
            break;

        case 'admin/photos':
        case 'admin/photos/new':
        case 'admin/photos/approved':
        case 'admin/photos/denied':
            $$('.photo_status .selectable').each(function(selectable) {
                var videoId = $(selectable).up('li.photo').id;
                var attributeName = 'media_status';
                var updateUrl = '/admin/update_photo';
                handleSelectable(selectable, videoId, attributeName, updateUrl);
            });
            break;
        
        case 'admin/hello_photos':
            $$('input.title').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
        
        case 'admin/talk':
            break;
            
        case 'admin/publications': 
            $$('h2.name a').each(function(link) {
                link.observe('click', function(event) {
                    var publication = link.up('li');
                    publication.down('.details').toggleClassName('hidden');
                    addHandlersForPublication(publication);
                });
            });
            break;
        
        case 'admin/create_show':
		    new Autocompleter.Local('show_bands', 'show_bands_results', bands, {'tokens': ','});
		    break;
		
		case 'admin/album':
    	    new Autocompleter.Local('recorded_song_title', 'recorded_song_title_results', songs);
    	    handleShowLink('add_song');
    	    $('show_edit_album').observe('click', function(event) {
    	        Event.stop(event)
                $(this).addClassName('hidden');
                $('edit_album').removeClassName('hidden');
                $('delete_album').removeClassName('hidden');
                $$('.delete_song').each(function(song) { song.removeClassName('hidden'); });
                return false;
            });
    	    break;
		    
		case 'admin/songs':
		    $$('#songs li').each(function(song) {
		        addHandlersForSong(song);
		    });
		    $('show_create_song').observe('click', function(event) {
		        Event.stop(event);
		        $(this).addClassName('hidden');
		        $('create_song').removeClassName('hidden');
                return false;
		    });
		    $('create_song').observe('submit', function(event) {
		        Event.stop(event);
                var url = $(this).readAttribute('action');
                var params = $(this).serialize(true);
                params.method = 'post'
                doAjax(url, params);
                $(this).reset();
		        return false;
		    });
		    break;
    
        case 'talk/create_topic':
            $$('#topic_title').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            $$('#topic_posts__content').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            break;
        
        case 'talk/topic':
            handleShowLink('reply');
            $$('textarea').each(function(input) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            });
            clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
            break;
	    
            
    }
    
    
    if ($('login_signup')) {
        start_button = new SwapButton('login_signup');
        $$('#login_signup form input').each(function(input) {
            var type = $(input).getAttribute('type');
            if (['text', 'password'].indexOf(type) != -1) {
                clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input);
                
            }
        });
        $('forgot_password').observe('click', function(event) {
            var email = $('login_email').getValue();
            if (email !== '' && email !== '<email>') {
                Event.stop(event);
                window.location.href = '/account/forgot_password?attempted_email=' + email;
            }
        });
    }
    
}

function handleShowShowDetails(nodes) {
    nodes.each(function(show_link) {
        show_link.observe('click', function(event) {
            Event.stop(event);
            var clicked = $(this);
            clicked.addClassName('hidden');
            clicked.adjacent('.summary')[0].down('.description').removeClassName('hidden');
            clicked.adjacent('.details')[0].removeClassName('hidden');
            return false; 
        });
    });
}

function handleSwapVideos(width, height) {
    $$('#more_videos img').each(function(thumbnail) {
        thumbnail.observe('click', function(event) {
            Event.stop(event);
            var videoId = $(thumbnail).getAttribute('id').replace('video_', '');
            changeYouTubeVideo(videoId, width, height);
            return false;
        });
    });
}

function handleShowLink(hiddenDivId) {
    var showLinkId = 'show_' + hiddenDivId;
    $(showLinkId).observe('click', function(event) {
        Event.stop(event);
        $(this).addClassName('hidden');
        $(hiddenDivId).removeClassName('hidden');
        return false;
    });
}

function showDiv(event) {
    Event.stop(event);
    var divName = this.id.replace('show_', '');
    var instructions = $(divName);
    $(this).hide();
    instructions.removeClassName('hidden');
    instructions.scrollTo();
}

function handleArrowKeysChangePhoto(event) {
    var increment;
    if (event.keyCode == 39) {
        increment = 1;
    } else if (event.keyCode == 37) {
        increment = -1;
    } else {
        return;
    }
    
    Event.stop(event);
    
    var newPhotoIndex;
    var photos = $$('#more_photos img');
    for (var i = 0; i < photos.length; i++) {
       if (photos[i].hasClassName('selected')) {
           newPhotoIndex = i + increment;
           break;
       } 
    }
    if (newPhotoIndex > photos.length - 1) { newPhotoIndex = 0; }
    if (newPhotoIndex < 0) { newPhotoIndex = photos.length - 1; }
    newPhoto = photos[newPhotoIndex];
    
    swapToSelectedPhoto(newPhoto, 'b');
}

function handleSwapPhotos(size) {
    $$('#more_photos img').each(function(img) {
        img.observe('click', function(event) {
            swapToSelectedPhoto(this, size);
        });
    });
}

function swapToSelectedPhoto(clicked, size) {
    var new_suffix = ((size === '') ? '' : '_' + size) + '.jpg';
    var src = clicked.src.replace('_t.jpg', new_suffix);
    var bigPhoto = $$('#photo img')[0];
    bigPhoto.src = src;
    bigPhoto.title = clicked.title;
    $$('img.selected').each(function(selected) { selected.removeClassName('selected'); });
    $(clicked).addClassName('selected');
    bigPhoto.up().href = clicked.title;
    bigPhoto.scrollTo();
    
}

// function setupYouTubeChromelessPlayer(divId) {
//     if (!$(divId)) { 
//         return;
//     }
//     var swfId = divId;
//     var playerJsName = divId;
//     var params = { allowScriptAccess: "always", bgcolor: "#cccccc" };
//     var swfUrl = 'http://www.youtube.com/apiplayer?enablejsapi=1&playerapiid=' + playerJsName;
//     var width = 450;
//     var height = 338;
//     swfobject.embedSWF(swfUrl, divId, width, height, "8", null, null, params);
//     $(swfId).observe('click', toggleYouTubeVideoPlayback);
// }
// 
// function onYouTubePlayerReady(playerId) {
//     you_tube_player = $("you_tube_player");
// }
// 
// function toggleYouTubeVideoPlayback(event) {
//     if (you_tube_player) {
//         var state = you_tube_player.getPlayerState();
//         if (state == 1) {
//             you_tube_player.pauseVideo();
//         } else {
//             you_tube_player.playVideo();
//         }
//         // TODO add checks for restarting etc? 
//     }
// }
// 
// function loadVideo(youTubeId, startTime) {
//     if (typeof(startTime) == 'undefined') {
//         startTime = 0;
//     }
//     if (you_tube_player) {
//         you_tube_player.loadVideoById(youTubeId, startTime);
//         you_tube_player.pauseVideo();
//     }
// }

function clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(input) {
    $(input).observe('focus', function(evt) {
        var value = $(this).getValue();
        if (typeof(this.original_value) == 'undefined') {
            this.original_value = value;
        } 
        if (value.match(/<[^>]+>/) && value == this.original_value) {
            $(this).value = '';
        }
    });
    $(input).observe('blur', function(evt) {
        var value = $(this).getValue();
        if (value === '') {
            $(this).value = this.original_value;
        }
    });
}

function handleSelectable(selectable, objectId, attributeName, updateUrl) {	
    var select = $(selectable).next('.wrapper').down('select');
    selectable.observe('click', function() {
        this.hide();
        var wrapper = select.up('.wrapper');
        wrapper.show();
        select.next('.editor_cancel').observe('click', function(event) {
            wrapper.hide();
            selectable.show();
            Event.stop(event);
        });
        if (!select.isObservingChange) { //only attach the listener on the first click, then ignore
            select.observe('change', function(event) {
                ajaxUpdateSelectable(this, objectId, attributeName, updateUrl);
                Event.stop(event);
            });
            select.isObservingChange = true;
        }
    });
}

function ajaxUpdateSelectable(select, objectId, attributeName, updateUrl) {
    select = $(select);
    var params = {
        object_id: objectId, 
        attribute_name: attributeName, 
        attribute_value: select.getValue()
    };
    var onComplete = function(data) {
        var wrapper = select.up('.wrapper');
        var selectable = wrapper.previous('.selectable');
        if ((data.status == 'success') && (select.getValue() == data.value[attributeName].id)) {
            selectable.update(select.options[select.selectedIndex].text);
        } else {
            alert("Update failed.");
        }
        wrapper.hide();
        selectable.show();
    };
    doAjax(updateUrl, params, onComplete);
}

// note: when doing rjs, callback won't get called. 
function doAjax(url, params, callback) {
    if (url === '') {
        url = window.location.href;
        url = url.substring(0, url.indexOf('?'));
    }
    
    if (typeof(callback) == 'undefined') {
        callback = function(data) {};
    }
    
    var method = typeof(params.method) == 'undefined' ? 'get' : params.method;
    
    params.authenticity_token = window._token;

    req = new Ajax.Request(
        url,
        { 
            parameters: params,
            asynchronous: true,
            evalScripts: true,
            method: method,
            onComplete: function(request) {
                eval('var data = ' + request.responseText + ';');
                callback(data);
            }
        }
    );
}

// if publicationId is not passed only attach for that publication
// otherwise attach to whole page
function addHandlersForPublication(publication) {
    publication = $(publication);
    
    publication.down('.show_add_email').observe('click', function(event) {
        Event.stop(event);
        $(this).up('li').down('.add_email').removeClassName('hidden');
        $(this).addClassName('hidden');
        return false;
    });
    
    var addEmailForm = publication.down('.add_email');
    addEmailForm.observe('submit', function(event) {
        Event.stop(event);
        var url = addEmailForm.readAttribute('action');
        var email = addEmailForm.down('input.email').getValue();
        var params = { 'email': email, 'method': 'post' };
        doAjax(url, params);
        return false;
    });
    clearInputHintOnFocusAndReplaceIfEmptyWhenUnfocusing(addEmailForm.down('input.email'));
    
    publication.select('.delete_email').each(function(link) {
        link.observe('click', function(event) {
            Event.stop(event);
            var url = link.readAttribute('href');
            var params = { 'method': 'delete' };
            doAjax(url, params);
            return false;
        });
    });    

}

function changeYouTubeVideo(videoId, width, height) {
    var newVideoHTML = 
    '<div class="player" id="video_' + videoId + '">' + 
        '<object width="' + width + '" height="' + height + '">' + 
            '<param name="movie" value="http://www.youtube.com/v/' + videoId + '"></param>' + 
            '<param name="wmode" value="transparent"></param>' + 
            '<embed src="http://www.youtube.com/v/' + videoId + '" type="application/x-shockwave-flash" wmode="transparent" width="' + width + '" height="' + height + '"></embed>' + 
        '</object>' + 
    '</div>';
    $('you_tube_player').update(newVideoHTML);
}

function addHandlersForSong(song) {
    song = $(song);
    song.down('.show_details').observe('click', function(event) {
        Event.stop(event);
        var details = song.down('.details');
        details.toggleClassName('hidden');
        var content = details.hasClassName('hidden') ? '+' : 'x';
        $(this).update(content);
        return false;
    });
}