WIDGETCONFIG = {
    toggle: function(widgetID) {
        if ($(widgetID)) {
            // Hide the current widget
            if (widgetID != WIDGETS.type) {
                $(WIDGETS.type).hide();
            }
            // Change the widget type and check it exists
            WIDGETS.type = widgetID;
            // Show the new widget and reset the state.
            if (!$(WIDGETS.type).visible()) {
                Effect.Appear(WIDGETS.type, {duration:0.3});
            }
            WIDGETCONFIG.update();
            WIDGETCONFIG.start();
            // Update the nav
            var items = $('widgetTypes').getElementsByTagName('li');
            for (var i = 0; i < items.length; i++) {
                if (items[i].firstChild.className == WIDGETS.type) {
                    var current = items[i];
                }
                $(items[i]).removeClassName('current');
            }
            current.addClassName('current');
            $('titlePane').className = WIDGETS.type;
            // Hide progression for apps
            if (WIDGETS.type == 'facebook' || WIDGETS.type == 'bebo') {
                $('progression').hide();
            } else {
                $('progression').show();
            }
            return true;
        }
    },
    
    progress: function(stage) {
        var steps = $('progression').getElementsByTagName('li');
        for (var i = 0; i < steps.length; i++) {
            if (i + 1 <= stage) {
                $(steps[i]).addClassName('current');
            } else {
                $(steps[i]).removeClassName('current');
            }
        }
    },
    
    buildParams: function(type) {
        var params = $H({
            widget: type,
            user: WIDGETS.user,
            colour: WIDGETS.colour,
            autostart: WIDGETS.autostart,
            from: WIDGETS.from,
            path: WIDGETS.path
        });
        switch (type) {
        case 'radio':
            params = params.merge($H({
                url: WIDGETS.url,
                size: WIDGETS.size
            }));
            break;
        case 'playlist':
            params = params.merge($H({
                size: WIDGETS.size,
                labelPlaylist: WIDGETS.labelPlaylist
            }));
            break;
        case 'quilt':
            params = params.merge($H({
                url: WIDGETS.url,
                orient: WIDGETS.orientation,
                height: WIDGETS.height,
                quiltType: WIDGETS.quiltType
            }));
            break;
        case 'chart':
            params = params.merge($H({
                chartType: WIDGETS.chartType,
                chartFriends: WIDGETS.chartFriends
            }));
            break;
        case 'tasteometer':
            params = params.merge($H({
            }));
            break;
        }
        if (WIDGETS.ljEmbed) {
            params = params.merge($H({
                ljEmbed: true
            }));
        }
        return params.toQueryString();
    },
    
    reset: function() {
        // Hide modules
        $('welcome').hide();
        
        $($('change').parentNode).hide();
        $($('reconfigure').parentNode).hide();
        
        $('sendCode').hide();
        $('codeSent').hide();
        
        if ($('sendBulletin')) {
            $('sendBulletin').hide();
            $('bulletinSent').hide();
        }
        
        $('embedCode').hide();
        $('ljInstructions').hide();
        
        if ($('myspace')) {
            $('myspace').hide();
            
            $('loginForm').hide();
            $('loginFailed').hide();
            $('embedForm').hide();
            $('embedFailed').hide();
            $('myspaceSuccess').hide();
        }
        $('tellFriends').hide();
        $('tellFriendsTitle').hide();
        $('friendsTold').hide();
        $('friendsToldAll').hide();
        
        $('signup').hide();
        
        $('otherWidgets').hide();
        var otherWidgets = $('otherWidgetItems').getElementsByTagName('li');
        for (var i = 0; i < otherWidgets.length; i++) {
            $(otherWidgets[i]).show();
        }
        
        $('scraper').hide();
        
        if ($('signupForm')) {
            $('signupForm').hide();
        }
    },
    
    start: function() {
        // Hide modules
        if (WIDGETS.type == 'chart') {
            $('oldCharts').show();
        } else {
            $('oldCharts').hide();
        }
        $(WIDGETS.type).show();
        WIDGETCONFIG.reset();
        WIDGETCONFIG.progress(1);
        // Find or Customise
        if (WIDGETS.type == 'facebook' || WIDGETS.type == 'bebo') {
            $('widgetEmbed').hide();
        } else if (WIDGETS[WIDGETS.type]) {
            $(WIDGETS.type + 'Finder').hide();
            Effect.Appear('widgetEmbed', {duration:0.3});
            Effect.Appear(WIDGETS.type + 'Config', {duration:0.3});
            // Show myspace share
            if ($('myspace') && WIDGETS.path == 'myspace') {
                $('myspace').show();
                $('loginForm').show();
            }
            // Show 'choose another' for radios and quilt
            if (WIDGETS.type == 'radio' || WIDGETS.type == 'quilt') {
                $($('change').parentNode).show();
            }
        } else {
            $(WIDGETS.type + 'Config').hide();
            $('widgetEmbed').hide();
            Effect.Appear(WIDGETS.type + 'Finder', {duration:0.3});
            // Show the scraper for radios and quilts
            ['radio', 'quilt'].each(function(type) {
                if (WIDGETS.type == type) {
                    Effect.Appear('scraper', {duration:0.3});
                } else {
                    $('scraper').hide();
                }
            });
        }
    },
    updatePreview: function(querystring, autostart) {
        var vertical = $('widgetPreview');
        var horizontal = $('widgetPreviewWide');
        var frame, loading;
        if (WIDGETS.type == 'facebook' || WIDGETS.type == 'bebo' || (WIDGETS.type == 'quilt' && WIDGETS.orientation == 'horizontal')) {
            frame = window.frames['previewWide'];
            loading = $('previewLoadingWide');
            WIDGETS.preview = 'widgetPreviewWide';
            WIDGETS.previewHeight = 41 + WIDGETS.heights[WIDGETS.height];
            vertical.height = 0;
            vertical.style.visibility = 'hidden';
            if ($('quiltWidgetTitle')) {
                $($('quiltWidgetTitle').parentNode).removeClassName('right');
                $($('quiltWidgetTitle').parentNode).addClassName('down');
            }
        } else {
            frame = window.frames['preview'];
            loading = $('previewLoading');
            WIDGETS.preview = 'widgetPreview';
            WIDGETS.previewHeight = 700;
            horizontal.height = 0;
            horizontal.style.visibility = 'hidden';
            if ($('quiltWidgetTitle')) {
                $($('quiltWidgetTitle').parentNode).removeClassName('down');
                $($('quiltWidgetTitle').parentNode).addClassName('right');
            }
        }
        if (querystring) {
            // Make sure the iframe is visible and set the search string
            $(WIDGETS.preview).height = WIDGETS.previewHeight;
            var current = WIDGETS.previewURL;
            WIDGETS.previewURL = '/widgets/preview/?' + querystring + (!autostart && '&autostart=0' || '');
            // Has the search string changed?
            if (WIDGETS.previewURL != current) {
                // Update the preview
                loading.style.visibility = 'visible';
                $(WIDGETS.preview).style.visibility = 'hidden';
                if (frame) {
                    frame.location.href = WIDGETS.previewURL;
                }
            } else {
                $(WIDGETS.preview).style.visibility = 'visible';
            }
        } else {
            $(WIDGETS.preview).height = 0;
            $(WIDGETS.preview).style.visibility = 'hidden';
        }
    },
    update: function() {
        var querystring;
        if (WIDGETS[WIDGETS.type] || WIDGETS.querytype == WIDGETS.type) {
            WIDGETS.querystring = WIDGETCONFIG.buildParams(WIDGETS.type);
            WIDGETS.querytype = WIDGETS.type;
            querystring = WIDGETS.querystring;
            // Update the configuration
            ['radio', 'quilt', 'chart'].each(function(type) {
                if (WIDGETS[type + 'Title'] != undefined && $(type + 'WidgetTitle')) {
                    $(type + 'WidgetTitle').update(WIDGETS[type + 'Title']);
                }
            });
            if ($(WIDGETS.type + '_' + WIDGETS.colour + 'Choice')) {
                $(WIDGETS.type + '_' + WIDGETS.colour + 'Choice').checked = true;
            }
            if ($(WIDGETS.type + '_' + WIDGETS.size + 'Choice')) {
                $(WIDGETS.type + '_' + WIDGETS.size + 'Choice').checked = true;
            }
            if ($(WIDGETS.type + '_' + WIDGETS.height + 'Choice')) {
                $(WIDGETS.type + '_' + WIDGETS.height + 'Choice').checked = true;
            }
            if ($(WIDGETS.type + '_' + WIDGETS.orientation + 'Choice')) {
                $(WIDGETS.type + '_' + WIDGETS.orientation + 'Choice').checked = true;
            }
            if ($(WIDGETS.type + '_' + WIDGETS.quiltType + 'Choice')) {
                $(WIDGETS.type + '_' + WIDGETS.quiltType + 'Choice').checked = true;
            }
            if ($(WIDGETS.type + 'Autostart')) {
                $(WIDGETS.type + 'Autostart').checked = (WIDGETS.autostart == 1);
            }
        }
        WIDGETCONFIG.updatePreview(querystring);
    },
    
    initialise: function(url, titles, types) {
        types.each(function(type) {
            WIDGETS[type + 'Title'] = titles[type];
            WIDGETS[type] = true;
        });
        if (url) {
            WIDGETS.url = url;
            WIDGETCONFIG.update();
        }
    },
    
    process: function(event) {
        // Get the clicked element and walk the DOM to find the corresponding input
        var autostart = $(WIDGETS.type + 'Autostart');
        if (event.element() == autostart) {
            WIDGETS.autostart = (autostart.checked && 1 || 0);
        }
        var item = event.findElement('dd');
        if (item) {
            var input = $(WIDGETS.type + '_' + item.className + 'Choice');
            if (input.match('input[type=radio]')) {
                input.checked = true;
            }
            if (input.match('input[type=checkbox]')) {
                WIDGETS[input.name] = (input.checked && 1 || 0);
            } else {
                WIDGETS[input.name] = input.value;
            }
            // Update the preview
            var classes = $(input).classNames();
            if (classes.include('preview')) {
                WIDGETCONFIG.update();
            }
        }
    },
    // Get a station based on user input
    getStationURL: function(prefix, action, submit, fromMyspace) {
        new Ajax.Request(action, {
            method: 'get',
            parameters: WIDGETS.searchstring,
            onComplete: function(request) {
                // Enable the submit button and hide progress
                if (submit) {
                    submit.disabled = false;
                    $(submit.parentNode).removeClassName('progress');
                }
                if (fromMyspace) {
                    $('scrapeNone').hide();
                } else {
                    $(prefix + 'SearchNone').hide();
                }
            },
            onSuccess: function(request) {
                WIDGETS.from = fromMyspace ? 'myspace_scrape' : 'search';
                WIDGETS.querystring = WIDGETCONFIG.buildParams(WIDGETS.type);
                // JSON validate and process the response
                var station = request.responseText.evalJSON();
                if (station.URL && station.Title) {
                    var url = station.URL;
                    var titles = {
                        radio: station.Title,
                        quilt: station.QuiltTitle
                    };
                    WIDGETCONFIG.initialise(url, titles, ['radio', 'quilt']);
                    if (station.Artists && station.Artists[0].Name && station.Artists[0].ID) {
                        WIDGETCONFIG.showMyspaceArtists(station.Artists);
                    } else {
                        WIDGETCONFIG.start();
                    }
                    return true;
                }
                WIDGETS.searchstring = null;
                // No station found
                if (fromMyspace) {
                    $('scrapeNone').show();
                } else {
                    $(prefix + 'SearchNone').show();
                }
            },
            onFailure: function(request) {
                WIDGETS.searchstring = null;
                $(prefix + 'SearchFailed').show();
            }
        });
    },
    // Show a table of artists scraped from MySpace
    showMyspaceArtists: function(artists) {
        var artistRow, deleteArtist, artistName, artistID;
        var tbody = document.createElement('TBODY');
        WIDGETS.myspaceArtists = {};
        artists.each(function(artist) {
            WIDGETS.myspaceArtists[artist.ID] = {
                enable: true,
                include: true,
                name: artist.Name
            };
            // Build up the table of artists
            artistID = 'a' + artist.ID;
            artistName = document.createElement('TD');
            artistName.innerHTML = artist.Name;
            deleteArtist = document.createElement('TD');
            deleteArtist.className = artistID;
            deleteArtist.innerHTML = '<a class="delete" href="#" onclick="return false;" title="Remove this artist from your radio player">Delete</a>';
            // Build the row
            artistRow = document.createElement('TR');
            artistRow.id = artistID;     
            artistRow.appendChild(artistName);
            artistRow.appendChild(deleteArtist);
            // Add to the tbody
            tbody.appendChild(artistRow);
        });
        $('scrapedArtistTable').appendChild(tbody);
        $('scraperForm').hide();
        Effect.Appear($('scrapedArtists'), {duration: 0.3});
    },
    // Show embed code
    getCode: function(target) {
        WIDGETS.querystring = WIDGETCONFIG.buildParams(WIDGETS.type);
        // Disable the form and show progress
        var form = $(WIDGETS.type + 'Form');
        $($('embedIt').firstChild).addClassName('progress');
        var parameters = WIDGETCONFIG.buildParams(WIDGETS.type);
        // Fire off the request
        new Ajax.Request('/tools/widgets/code/', {
            method: 'get',
            parameters: parameters,
            onSuccess: function(request) {
                // Enable the form and hide progress
                if (target.match('input')) {
                    target.disabled = false;
                }
                $($('embedIt').firstChild).removeClassName('progress');
                // Process the response
                if (request.responseText) {
                    $('embedArea').value = request.responseText;
                    $(WIDGETS.type).hide();
                    $(WIDGETS.type + 'Config').hide();
                    $('widgetEmbed').hide();
                    if ($('myspace')) {
                        $('myspace').hide();
                    }
                    $($('change').parentNode).hide();
                    $('oldCharts').hide();
                    $($('reconfigure').parentNode).show();
                    $('sendCode').show();
                    Effect.Appear('embedCode', {duration:0.3});
                    if ($('signupForm')) {
                        Effect.Appear('signup', {duration:0.3});
                    }
                    if (WIDGETS.autostart) {
                        WIDGETCONFIG.updatePreview(WIDGETS.querystring, true);
                    }
                    if (WIDGETS.ljEmbed) {
                        $('ljInstructions').show();
                        WIDGETS.ljEmbed = false;
                    }
                    WIDGETCONFIG.progress(2);
                    return true;
                }
            }
        });
    },
    
    conclude: function() {
        if ($('signupForm')) {
            Effect.Appear('signup', {duration:0.3});
        } else {
            $('tellFriends').show();
            var otherWidgets = $('otherWidgetItems').getElementsByTagName('li');
            for (var i = 0; i < otherWidgets.length; i++) {
                if (otherWidgets[i].className == WIDGETS.type) {
                    $(otherWidgets[i]).hide();
                }
            }
            Effect.Appear('otherWidgets', {duration:0.3});
        }
    }
};

WIDGETEMBED = {
    sendCode: function() {
        var submit = $('sendCodeSubmit');
        submit.disabled = true;
        $(submit.parentNode).addClassName('progress');
        $('sendCodeFailed').hide();
        var email = encodeURIComponent($F('sendCodeEmail'));
        var postBody = WIDGETCONFIG.buildParams(WIDGETS.type) + '&email=' + email;
        new Ajax.Request('/ajax/widgets/sendcode/', {
            method: 'post',
            postBody: postBody,
            onComplete: function(request) {
                $(submit.parentNode).removeClassName('progress');
                submit.disabled = false;
            },
            onSuccess: function(request) {
                var outcome = request.responseText.evalJSON();
                if (outcome.Sent) {
                    WIDGETCONFIG.progress(3);
                    $('embedCode').hide();
                    $('ljInstructions').hide();
                    $('sendCode').hide();
                    $('codeSent').show();
                    if ($('bulletinLogin')) {
                        $('bulletinLogin').show();
                        Effect.Appear('sendBulletin', {duration:0.3});
                    } else {
                        Effect.Appear('tellFriends', {duration:0.3});
                    }
                    return true;
                }
                // Show failure
                $('sendCodeFailed').show();
            },
            onFailure: function(request) {
                $('sendCodeFailed').show();
            }
        });
    },
    
    tellFriends: function() {
        var submit = $('tellFriendsSubmit');
        submit.disabled = true;
        $('friendsTold').style.visibility = 'hidden';
        $(submit.parentNode).addClassName('progress');
        $('tellFriendsFailed').hide();
        var friend = $F('tellFriendSelect');
        var postBody = WIDGETCONFIG.buildParams(WIDGETS.type) + '&friend=' + friend;
        new Ajax.Request('/ajax/widgets/tellfriends/', {
            method: 'post',
            postBody: postBody,
            onComplete: function(request) {
                $(submit.parentNode).removeClassName('progress');
                submit.disabled = false;
            },
            onSuccess: function(request) {
                var outcome = request.responseText.evalJSON();
                if (outcome.Sent) {
                    $('codeSent').hide();
                    WIDGETCONFIG.conclude();
                    if ($('myspace')) {
                        $('myspaceSuccessMessage').hide();
                    }
                    if (friend == 'all') {
                        $('friendsTold').hide();
                        Effect.Appear('friendsToldAll', {duration:0.3});
                        $('tellFriends').hide();
                    } else {
                        $('friendsToldAll').hide();
                        $('friendsTold').style.visibility = 'visible';
                        Effect.Appear('friendsTold', {duration:0.3});
                        $('tellFriendsTitle').hide();
                    }
                    return true;
                }
                // Show failure
                $('tellFriendsFailed').show();
            },
            onFailure: function(request) {
                $('tellFriendsFailed').show();
            }
        });
    },
    
    // Login to Myspace and send a bulletin to your friends
    myspaceLogin: function() {
        // Serialise the form, hide submit button and show the progress
        WIDGETS.myspaceUsername = encodeURIComponent($F('embedUsername'));
        WIDGETS.myspacePassword = encodeURIComponent($F('embedPassword'));
        var submit = $('loginSubmit');
        submit.disabled = true;
        $(submit.parentNode).addClassName('progress');
        $('loginFailed').hide();
        var postBody = 'username=' + WIDGETS.myspaceUsername + '&password=' + WIDGETS.myspacePassword;
        // Fire off login request
        new Ajax.Request('/ajax/widgets/myspacesections/', {
            method: 'post',
            postBody: postBody,
            onComplete: function() {
                submit.disabled = false;
                $(submit.parentNode).removeClassName('progress');
            },
            onSuccess: function(request) {
                var myspace = request.responseText.evalJSON();
                if (myspace.Sections) {
                    // Build up the options
                    var option;
                    for (var i = 0; i < myspace.Sections.length; i++) {
                        option = document.createElement('OPTION');
                        option.innerHTML = myspace.Sections[i].Text;
                        option.value = myspace.Sections[i].Value;
                        if (myspace.Sections[i].Value == 'MusicText' || myspace.Sections[i].Value == 'influences') {
                             option.selected = true;
                        }
                        $('embedSection').appendChild(option);
                    }
                    // Hide login form and insert section select options from response
                    WIDGETEMBED.login = true;
                    $('loginForm').hide();
                    Effect.Appear('embedForm', {duration:0.3});
                    return true;
                }
                // Show failure
                $('loginFailed').show();
            },
            onFailure: function() {
                $('loginFailed').show();
            }
        });
    },
    
    // Embed code on MySpace
    myspaceEmbed: function(action) {
        // Serialise the form, disable the submit button and show the progress
        WIDGETS.myspaceUsername = encodeURIComponent($F(action + 'Username'));
        WIDGETS.myspacePassword = encodeURIComponent($F(action + 'Password'));
        var postBody = WIDGETCONFIG.buildParams(WIDGETS.type) + '&username=' + WIDGETS.myspaceUsername + '&password=' + WIDGETS.myspacePassword;
        if (action == 'embed') {
            var section = $F('embedSection');
            var bulletin = $F('embedBulletin') || 0;
            postBody = postBody + '&embed=1&section=' + section + '&bulletin=' + bulletin;
        } else if (action == 'bulletin') {
            postBody = postBody + '&bulletin=1';
        }
        var submit = $(action + 'Submit');
        submit.disabled = true;
        $(submit.parentNode).addClassName('progress');
        $('embedFailed').hide();
        if ($('bulletinFailed')) {
            $('bulletinFailed').hide();
        }
        // Fire off embed request
        new Ajax.Request('/ajax/widgets/myspaceembed/', {
            method: 'post',
            postBody: postBody,
            onComplete: function(request) {
                submit.disabled = false;
                $(submit.parentNode).removeClassName('progress');
            },
            onSuccess: function(request) {
                var myspace = request.responseText.evalJSON();
                if (myspace.URL) {
                    // Get the profile URL from the response and show the success screen
                    switch (action) {
                    case 'bulletin':
                        if (myspace.Bulletin) {
                            // Hide login form and insert section select options from response
                            $('codeSent').hide();
                            $('sendBulletin').hide();
                            Effect.Appear('bulletinSent', {duration:0.3});
                            WIDGETCONFIG.conclude();
                            return true;
                        }
                        break;
                    case 'embed':
                        if (myspace.Embed) {
                            if (myspace.Bulletin) {
                                $('myspaceSuccessBulletin').show();
                            }
                            $('myspaceProfile').href = 'http://' + myspace.URL;
                            $('myspaceProfile').innerHTML = myspace.URL;
                            $(WIDGETS.type).hide();
                            $(WIDGETS.type + 'Config').hide();
                            $('widgetEmbed').hide();
                            $($('change').parentNode).hide();
                            $('oldCharts').hide();
                            $($('reconfigure').parentNode).show();
                            $('myspace').hide();
                            Effect.Appear('myspaceSuccess', {duration:0.3});
                            WIDGETCONFIG.conclude();
                            WIDGETCONFIG.progress(3);
                            if (WIDGETS.autostart) {
                                WIDGETCONFIG.updatePreview(WIDGETS.querystring, true);
                            }
                            return true;
                        }
                        break;
                    }
                } else {
                    $(action + 'Failed').show();
                }
                // Show failure
                $(action + 'Failed').show();
            },
            onFailure: function(request) {
                $(action + 'Failed').show();
            }
        });
    },
    embedNifty: function() {
        $($('embedIt').firstChild).addClassName('progress');
        // Serialise the widget
        var postBody = WIDGETCONFIG.buildParams(WIDGETS.type);
        // Fire off hash request
        new Ajax.Request('/ajax/widgets/niftyparams/', {
            method: 'post',
            postBody: postBody,
            onSuccess: function(request) {
                var nifty = request.responseText.evalJSON();
                if (nifty.Code && nifty.Hash) {
                    $('niftyEmbedCode').value = nifty.Code;
                    $('niftyEmbedHash').value = nifty.Hash;
                    $('niftyEmbedForm').submit();
                    return true;
                }
                // Show failure
                $('niftyFailed').show();
                $($('embedIt').firstChild).removeClassName('progress');
            },
            onFailure: function(request) {
                $('niftyFailed').show();
                $($('embedIt').firstChild).removeClassName('progress');
            }
        });
    }
};

// Sign up
SIGNUP = {
    hideErrors: function() {
        // Hide error div
        $('signupFailed').hide();
        // Hide error messages
        var errorList = $('signupFailed').getElementsByTagName('span');
        for (var i = 0; i < errorList.length; i++) {
            $(errorList[i]).hide();
        }
    },
    
    process: function() {
        // Hide submit/errors and show progress
        SIGNUP.hideErrors();
        var submit = $('createprofile');
        submit.disabled = true;
        $(submit.parentNode).addClassName('progress');
        // Serialise the form
        var username = encodeURIComponent($F('username'));
        var password = encodeURIComponent($F('pword'));
        var passwordConfirm = encodeURIComponent($F('confirmpw'));
        var email = encodeURIComponent($F('email'));
        var newsletter = $('newsletter').checked && 1 || '';
        var terms = $('terms').checked && 1 || '';
        var postBody = 'username=' + username + '&email=' + email + '&pword=' + password + '&confirmpw=' + passwordConfirm + '&newsletter=' + newsletter + '&terms=' + terms;
        // Fire off the request
        new Ajax.Request('/ajax/join/', {
            method: 'post',
            postBody: postBody,
            onLoaded: function(request) {
                // Hide the progress/errors
                SIGNUP.hideErrors();
                submit.disabled = false;
                $(submit.parentNode).removeClassName('progress');
            },
            onSuccess: function(request) {
                var account = request.responseText.evalJSON();
                if (account.User) {
                    // Reload the page with a welcome message
                    window.location.search = 'welcome=1&widget=' + WIDGETS.type;
                    return true;
                }
                $(account.Error).show();
                $('signupFailed').show();
                return false;
            },
            onFailure: function(request) {
                // Hide progress/error messages and show submit/error (HTTP Error/blank response)
                $('signupFailed').show();
            }
        });
        return false;
    }
};

// Initialise
document.observe('dom:loaded', function(e) {
    // Widget switcher
    $$('.toggleWidget').each(function(el) {
        el.observe('click', function(event) {
            var target = event.element();
            if (target.match('a')) {
                var widgetID = target.className;
                WIDGETCONFIG.toggle(widgetID);
            }
            event.stop();
        });
    });

    // Configuration listener
    $$('.configForm').each(function(form) {
        form.observe('click', WIDGETCONFIG.process);
    });

    // Choose a user station
    if ($('chooseURL')) {
        $('chooseURL').onsubmit = function() {
            WIDGETS.from = 'station_choice';
            var url = $F('stationURL');
            WIDGETS.searchstring = null;
            var titles = {radio: $(url.replace(/\//g, '-')).innerHTML};
            WIDGETCONFIG.initialise(url, titles, [WIDGETS.type]);
            WIDGETCONFIG.start();
            return false;
        };
    }
    
    // Choose a quilt type
    if ($('chooseQuilt')) {
        $('chooseQuilt').onsubmit = function() {
            var url = $F('stationURL');
            WIDGETS.from = 'quilt_choice';
            WIDGETS.quiltType = $F('quiltChoice');
            WIDGETS.searchstring = null;
            var titles = {
                radio: $(url.replace(/\//g, '-')).innerHTML,
                quilt: $(WIDGETS.quiltType + 'QuiltChoice').title
            };
            WIDGETCONFIG.initialise(url, titles, ['radio', 'quilt']);
            WIDGETCONFIG.start();
            return false;
        };
    }
    
    // Change chart title
    if ($('chartType')) {
        $('chart_typeChoice').onchange = function() {
            WIDGETS.chartType = $F('chart_typeChoice');
            if (WIDGETS.chartType == 'recenttracks') {
                $($('chart_friendChoice').parentNode).show();
            } else {
                $($('chart_friendChoice').parentNode).hide();
            }
            var titles = {
                chart: $($F('chart_typeChoice') + 'Chart').innerHTML
            };
            WIDGETCONFIG.initialise(null, titles, ['chart']);
            WIDGETCONFIG.update();
            return false;
        };
    }
    
    ['radio', 'quilt'].each(function(prefix) {
        // Get a station based on user input
        $(prefix + 'Search').onsubmit = function() {
            // Hide errors
            $(prefix + 'SearchNone').hide();
            $(prefix + 'SearchFailed').hide();
            $(prefix + 'SearchEmpty').hide();
            // Serialise the form
            var type = $F(prefix + 'SearchType');
            var query = encodeURIComponent($F(prefix + 'SearchQ'));
            if (type == 'artist' && WIDGETS.type == 'quilt') {
                WIDGETS.quiltType = 'album';
            }
            if (!query) {
                // Warn about empty query
                $(prefix + 'SearchEmpty').show();
            } else {
                var searchstring = 'type=' + type + '&q=' + query;
                // Has the searchstring changed?
                if (WIDGETS.searchstring != searchstring) {
                    WIDGETS.searchstring = searchstring;
                    // Disable the submit button and show progress
                    var submit = $(prefix + 'SearchSubmit');
                    $(submit.parentNode).addClassName('progress');
                    submit.disabled = true;
                    // Get the new URL
                    WIDGETCONFIG.getStationURL(prefix, '/ajax/widgets/tasteurl/', submit);
                } else {
                    if (WIDGETS.searchstring) {
                        WIDGETS[WIDGETS.type] = true;
                    }
                    WIDGETCONFIG.start();
                }
            }
            return false;
        };
        // Set the default hint text
        if ($(prefix + 'SearchQ').value == '') {
            $(prefix + 'SearchQ').addClassName('hint');
            $(prefix + 'SearchQ').value = HINTS.current;
        }
        // Watch for search type changes
        $(prefix + 'SearchType').observe('click', function(event) {
            var value = $(prefix + 'SearchQ').value;
            var selected = HINTS[event.element().value];
            // Is the current value a hint or blank?
            if (value == HINTS.current || value == '') {
                // Change the hint
                $(prefix + 'SearchQ').addClassName('hint');
                $(prefix + 'SearchQ').value = selected;
            }
            // Update the current hint
            HINTS.current = selected;
        });
        // Clear the input on focus if it's the hint
        $(prefix + 'SearchQ').observe('focus', function(event) {
            var value = $(prefix + 'SearchQ').value;
            if (value == HINTS.current) {
                $(prefix + 'SearchQ').removeClassName('hint');
                $(prefix + 'SearchQ').value = '';
            }
        });
        // Restore the hint on blur if the input is empty
        $(prefix + 'SearchQ').observe('blur', function(event) {
            var value = $(prefix + 'SearchQ').value;
            if (value == '') {
                $(prefix + 'SearchQ').addClassName('hint');
                $(prefix + 'SearchQ').value = HINTS.current;
            }
        });
    });
    
    // Get a station from a MySpace URL
    if ($('scraperForm')) {
        $('scraperForm').onsubmit = function() {
            // Serialise the form
            var url = $F('scrapeURL');
            var searchstring = 'url=' + url;
            // Has the searchstring changed?
            if (WIDGETS.searchstring != searchstring) {
                WIDGETS.searchstring = searchstring;
                // Disable the submit button and show progress
                var submit = $('scrapeSubmit');
                $(submit.parentNode).addClassName('progress');
                submit.disabled = true;
                // Get the new URL
                WIDGETCONFIG.getStationURL(WIDGETS.type, '/ajax/widgets/myspaceTaste/', submit, true);
            } else {
                if (WIDGETS.searchstring) {
                    WIDGETS[WIDGETS.type] = true;
                }
                WIDGETCONFIG.start();
            }
            return false;
        };
        // Toggle MySpace artists
        $('scrapedArtistTable').observe('click', function(event) {
            if (event.element().match('a')) {
                var row = event.findElement('tr');
                if (row) {
                    artistID = row.id.replace('a', '');
                    if (row.hasClassName('removed')) {
                        WIDGETS.myspaceArtists[artistID].enable = true;
                        $(row).removeClassName('removed');
                    } else {
                        WIDGETS.myspaceArtists[artistID].enable = false;
                        $(row).addClassName('removed');
                    }
                }
            }
        });
        // Configure MySpace radio player
        $('scrapeConfig').observe('click', function(event) {
            var enabled = [];
            var included = [];
            for (id in WIDGETS.myspaceArtists) {
                // Get the currently included artists
                if (WIDGETS.myspaceArtists[id].include) {
                    included[included.length] = id;
                }
                // Get the newly enabled artists
                if (WIDGETS.myspaceArtists[id].enable) {
                    enabled[enabled.length] = id;
                }
                // Include the newly enabled artists
                WIDGETS.myspaceArtists[id].include = WIDGETS.myspaceArtists[id].enable;
            }
            if (enabled.length != 0) {
                WIDGETS.searchstring = 'type=multi&q=' + enabled.join(',');
                // Have the enabled artists changed?
                if (enabled.join(',') != included.join(',')) {
                    Effect.BlindUp('enabledNone', {duration:0.1});
                    // Disable the submit button and show progress
                    var submit = $('scrapeConfig');
                    $(submit.parentNode).addClassName('progress');
                    submit.disabled = true;
                    // Get the new URL
                    WIDGETCONFIG.getStationURL(WIDGETS.type, '/ajax/widgets/tasteurl/', submit);
                } else {
                    // Customise
                    WIDGETS[WIDGETS.type] = true;
                    WIDGETCONFIG.start();
                }
            } else {
                // Need to have at least one artist enabled
                $('enabledNone').show();
            }
            event.stop();
        });
    }
    
    // Show the embed code
    $$('.getCode').each(function(codeLink) {
        codeLink.observe('click', function(event) {
            var target = event.findElement('a');
            if (target && target.hasClassName('getCode')) {
                WIDGETCONFIG.getCode(target);
            }
            event.stop();
        });
    });
    // Change the widget
    $$('.change').each(function(changeLink) {
        changeLink.observe('click', function(event) {
            WIDGETS[WIDGETS.type] = false;
            WIDGETCONFIG.start();
            event.stop();
        });
    });
    // Reconfigure
    $('reconfigure').observe('click', WIDGETCONFIG.start);
    
    // Show embedding options
    if ($('myspace')) {
        $$('.showEmbed').each(function(showMyspace) {
            showMyspace.observe('click', function(event) {
                $(WIDGETS.type).hide();
                $(WIDGETS.type + 'Config').hide();
                $('widgetEmbed').hide();
                $($('change').parentNode).hide();
                $('oldCharts').hide();
                $($('reconfigure').parentNode).show();
                $('myspace').show();
                if (WIDGETEMBED.login) {
                    new Effect.Appear('embedForm', {duration:0.3});
                } else {
                    new Effect.Appear('loginForm', {duration:0.3});
                }
                WIDGETCONFIG.progress(2);
                event.stop();
            });
        });
        // Embed/post a bulletin
        ['embed', 'bulletin'].each(function(action) {
            if ($(action + 'Form')) {
                $(action + 'Form').onsubmit = function() {
                    WIDGETEMBED.myspaceEmbed(action);
                    return false;
                };
            }
        });
    }
    
    // Post to Nifty
    if ($('niftyEmbed')) {
        $('niftyEmbed').observe('click', function(event) {
            WIDGETEMBED.embedNifty();
            event.stop();
        });
    }
    
    // Login to Netlog
    if ($('netlogLogin')) {
        $('netlogLogin').observe('click', function(e) {
            e.stop();
            
            var next = '?' + WIDGETS.querystring + '&path=netlog';
            var app_id = WIDGETS.netlog_app_ids[WIDGETS.type];
            $('netlogLoginNext').value = next;
            $('netlogLoginAppID').value = app_id;
            var arguments = $('netlogLoginForm').serialize();
            var loginURL = $('netlogLoginForm').action + arguments;
            location = loginURL;
        });
    }
    
    // Login to Myspace
    if ($('myspace')) {
        if ($('loginForm')) {
            $('loginForm').onsubmit = function() {
                WIDGETEMBED.myspaceLogin();
                return false;
            };
        }
    }
    // Email the code
    $('sendCodeForm').onsubmit = function() {
        WIDGETEMBED.sendCode();
        return false;
    };
    // Tell friends
    if ($('tellFriendsForm')) {
        $('tellFriendsForm').onsubmit = function() {
            WIDGETEMBED.tellFriends();
            return false;
        };
    }
    
    if (false && $('signupForm')) { // Turned off inline signup until we can improve it with Captcha etc...
        // Show sign up form
        $$('.signUp').each(function(signupLink) {
            signupLink.observe('click', function(event) {
                WIDGETCONFIG.reset();
                $(WIDGETS.type).hide();
                $(WIDGETS.type + 'Config').hide();
                $('widgetEmbed').hide();
                $(WIDGETS.type + 'Finder').hide();
                $($('change').parentNode).hide();
                $('oldCharts').hide();
                $($('reconfigure').parentNode).show();
                Effect.Appear('signupForm', {duration:0.3});
                event.stop();
            });
        });
        
        $('signupForm').onsubmit = SIGNUP.process;
    }
});