/* please shoot me now for creating all these globals */

var timeoutedMessage = null;
var timeoutId = null;
var visibleButtons = null;
var originalMsgBody = Array;
var lastScrollTime = new Date;
var animatedMessages = Array;
var waitingOnPost = false;
var postTrans = '';
var previewTrans = '';
var shoutWarned = false;
var typeChanged = Array;
var postSubmitSuccess = false;
var postFailedOnce = false;

jQuery( document ).ready( function() {
    var msgId = document.location.hash.substring( 1 );
    if ( msgId != '' && !isNaN( msgId ) ) {
        if ( !jQuery( '#message_' + msgId ).length ) {
            jQuery.scrollTo( '.unloaded', 500, { easing: 'swing', offset: -20 } );
            if ( jQuery( '.loadsome' ).length ) {
                jQuery( '.loadsome' ).click();
            } else {
                jQuery( '.loadall' ).click();
            }
        }
    }

	if ( !jQuery( '#addrecipient' ).size() ) {
        return;
    }

	jQuery( '#addrecipient' ).autocomplete( '/parts/users/contactsautocomplete', {
		extraParams : {
			'recipients': function() {
				return jQuery( '#receivers' ).val();
			}
		}
	}).result( function( event, data, formatted ) {
		addPMRecipient( data );
	});
});

function checkForNewMessages() {    
    if ( undefined !== window.checkingForNew && checkingForNew ) {
        return;
    }
    checkingForNew = true;

    jQuery( '#toolbox .indicator' ).fadeIn( 3000 );
	setTimeout( 'timeoutNewMessagesCheck()', 20000 );
	
    jQuery.post(
        '/parts/forum/messages/loadnew',
        { 
            last_message_id: jQuery( '#messages_list .message:last' )
                .attr( 'id' ).substr( 8 ),
            thread_id: threadId
        },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                return;
            }
            
            if ( Result[1].length ) {
				// check see if the last new message is the same as the 
				// last one already on the page. don't show phantom
				// double posts!
				var alreadyThere = false;
				var lastOnPage = jQuery( '#messages_list .message:last' );
				jQuery( Result[1] ).each( function() {
					if ( this.id == lastOnPage.attr( 'id' ) ) {
						alreadyThere = true;
					}
				} );
				
				if ( !alreadyThere ) {
                	jQuery( Result[1] ).appendTo( '#messages_list' ).slideDown();
                    jQuery( 'a[rel^=lightbox]' )
                        .slimbox( {}, null, function( el ) {
		                    return ( this == el ) || 
                                ( ( this.rel.length > 8 ) && 
                                  ( this.rel == el.rel ) );
	                    } );
				}
            }
						
            jQuery( '#toolbox .indicator' ).stop().fadeOut( 3000 );
            pollLock = false;

            if ( waitingOnPost ) {
                waitingOnPost = false;

                jQuery( '#previewsgohere .message.preview' ).slideUp();
                jQuery( '#postbody' ).attr( 'value', '' );
                jQuery( '#postbutton' ).val( postTrans ).blur();                
                jQuery( '#closednotice' ).slideUp();
            }
            
            checkingForNew = false;
        }
    );
}

function timeoutNewMessagesCheck() {
	if ( !checkingForNew ) {
		return;
	}
	
	jQuery( '#toolbox .indicator' ).stop().fadeOut( 3000 );
    pollLock = false;
	checkingForNew = false;
}

function updateAreaLists() {
    jQuery( '.areas_list' ).each( function() {

        if ( !jQuery( this ).parents( '.area-container' ).hasClass( 'expanded' ) ) {
            return true;
        }

        var group = this.parentNode.id.replace( 'group', '' );

        jQuery.post( '/parts/forum/areas/getlist', { group: group }, function( responseText ) { 
            Result = eval( responseText );
             
            jQuery( Result[1] ).find( '.area' ).each( function() {
                var areaId = this.id.substr( 5 );
                var newCounts = jQuery( this ).find( '.counts' ).text();
                var oldCounts = jQuery( '#area_' + areaId + ' .counts' ).text();
                
                if ( newCounts == oldCounts ) {
                    return true;
                }
                
                var Area = jQuery( '#area_' + areaId );
                var Counts = jQuery( '#area_' + areaId + ' .counts' );
                var Desc = jQuery( '#area_' + areaId + ' .description' );
                
                Counts.fadeOut( 150, function() { 
                    Counts.text( newCounts ).fadeIn( 150 );
                } );
                
                var newNew = newCounts.search( 'new' );
                var oldNew = oldCounts.search( 'new' );

                if ( newNew == oldNew ) {
                    return true;
                }

                if ( newNew > -1 ) {
                    if ( site == 'serato' ) {
                        Area.css( backgroundColor, '#fff' ).animate( 
                            { backgroundColor: '#fb0', borderBottomColor: '#c80' }, 
                            { queue: false, duration: 300 }
                        );
                        Desc.animate( { color: '#000' }, { queue: false, duration: 300 } );
                        Counts.animate( 
                            { color: '#000', backgroundColor: '#fb0' }, 
                            { queue: false, duration: 300 } 
                        );
                    } else {
                        Area.css( backgroundColor, '#fff' ).animate( 
                            { backgroundColor: '#fe8', borderBottomColor: '#999' }, 
                            { queue: false, duration: 300 }
                        );
                        Counts.animate( { backgroundColor: '#fe8' }, 
                            { queue: false, duration: 300 } );
                    }
                } else {
                    Area.animate( 
                        { backgroundColor: '#fff', borderBottomColor: '#bbb' }, 
                        { queue: false, duration: 300 }
                    );
                    Counts.animate( { backgroundColor: '#fff' }, 
                        { queue: false, duration: 300 } );
                    if ( site == 'serato' ) {
                        Desc.animate( { color: '#666' }, { queue: false, duration: 300 } );
                        Counts.animate( { color: '#666' }, { queue: false, duration: 300 } );
                    }
                }
            } );
        } );
    } );
}

function updateThreadsList() {
    if ( jQuery( '#sticky_threads' ).length ) {
        updateThreads( 'sticky_threads' );
    }
    updateThreads( viewType );
   
    function updateThreads( type ) {
        jQuery.post(
            '/parts/forum/threads/updatedlist', 
            { area_id: areaId, type: type },
            function( updatedList ) {
                var UpdatedThreads = jQuery( updatedList );
                
                // scan updated list for new threads
                var newThreads = 0;
                UpdatedThreads.find( '.thread' ).each( function() {
                    if ( !jQuery( '#' + this.id ).length ) {
                        newThreads++;
                    }
                } );
                if ( newThreads ) {
                    if ( newThreads == 1 ) {
                        newThreads += ' new discussion';
                    } else {
                        newThreads += ' new discussions';
                    }
                    jQuery( '.list_updated.' + type ).text( newThreads ).fadeIn();
                    return;
                }

                // fix the thread list heights to avoid slight page height 
                // jitter when threads move
                jQuery( '#' + type + ' .threads_list' )
                    .css( 'height', jQuery( '#' + type + ' .threads_list' ).height() );
                
                // step through updated list and move/update
                UpdatedThreads.find( '.thread' ).each( function( i ) {
                    var NewThread = jQuery( this );
                    var OldThread = jQuery( '#' + NewThread.attr( 'id' ) );
                    var newCounts = NewThread.find( '.counts' ).text();
                    var oldCounts = OldThread.find( '.counts' ).text();

                    if ( newCounts != oldCounts ) {
                        updateCountAndColour( 
                            NewThread, OldThread, newCounts, oldCounts, i + 1 );
                    }
                } );
            } 
        );

        function updateCountAndColour( NewThread, OldThread, newCounts, oldCounts, newOrder ) {
            var Counts = OldThread.find( '.counts' );
            var Starter = OldThread.find( '.starter' );

            var classes = OldThread.attr( 'class' ).split( ' ' );
            for ( j = 0; classes[j]; j++ ) {
                if ( classes[j].search( 'pos' ) != -1 ) {
                    var oldOrder = classes[j].substr( 3 );
                    break;
                }
            }

            Counts.fadeOut( 150, function() { 
                Counts.text( newCounts ).fadeIn( 150, function() {
                    if ( newOrder != oldOrder ) {
                        move( NewThread, OldThread, newOrder, oldOrder, type );
                    }
                } );
            } );

            var newNew = newCounts.search( 'new' );
            var oldNew = oldCounts.search( 'new' );
            
            if ( newNew == oldNew ) {
                return true;
            }

            if ( newNew > -1 ) {           
                var threadId = OldThread.attr( 'id' ).substr( 7 );
                OldThread.find( 'a' )
                    .attr( 'href', OldThread.find( 'a' ).attr( 'href' ) + '#new' )
                    .bind( 'click', function() {
                        fadeThread( threadId );
                    } );
                
                if ( site == 'serato' ) {
                    OldThread.css( 'backgroundColor', '#fff' ).animate( 
                        { backgroundColor: '#fb0', borderBottomColor: '#c80' }, 
                        { queue: false, duration: 300 }
                    );
                    Starter.animate( { 'color': '#000' }, 
                        { queue: false, duration: 300 } );
                    Counts.animate( { color: '#000' }, 
                        { queue: false, duration: 300 } );
                } else {
                    OldThread.css( 'backgroundColor', '#fff' ).animate( 
                        { backgroundColor: '#fe8', borderBottomColor: '#999' }, 
                        { queue: false, duration: 300 }
                    );
                }
            } else {
                OldThread.animate( 
                    { backgroundColor: '#fff', borderBottomColor: '#bbb' }, 
                    { queue: false, duration: 300 }
                );
                OldThread.find( '.prefix' ).hide();
                if ( site == 'serato' ) {
                    Starter.animate( { color: '#666' }, 
                        { queue: false, duration: 300 } );
                    Counts.animate( { color: '#666' }, 
                        { queue: false, duration: 300 } );
                }
            }
        }

        function move( NewThread, OldThread, newOrder, oldOrder, listType ) {
            var oldPos = OldThread.position();
            var newPos = jQuery( '#' + listType + ' .pos' + newOrder ).position();
            var FinalThread = OldThread.clone( true )
                .insertBefore( '#' + listType + ' .pos' + newOrder );
            OldThread.attr( 'id', '' );
            var MovingThread = OldThread.clone();

            // renumber the threads list
            jQuery( '#' + listType + ' .thread' ).each( function( i ) {
                var newPosClass = 'pos' + ( i + 1 );
                var classes = jQuery( this ).attr( 'class' ).split( ' ' );
                for ( j = 0; classes[j]; j++ ) {
                    if ( classes[j].search( 'pos' ) != -1 ) {
                        var oldPosClass = classes[j];
                        break;
                    }
                }
                jQuery( this ).removeClass( oldPosClass ).addClass( newPosClass );
            } );

            // slide the moving clone from old position to new
            MovingThread.attr( 'id', '' ).appendTo( '#' + listType + ' .threads_list' )
                .css( { 
                    position: 'absolute', top: oldPos.top + 'px', 
                    width: OldThread.css( 'width' ) 
                } )
                .animate( { top: newPos.top + 'px' }, { queue: false, duration: 300 } );

            // shrink the original thread then remove it
            OldThread.css( 'opacity', 0 )
                .animate( { height: 0, paddingTop: 0, paddingBottom: 0, marginBottom: 0 },
                    { queue: false, duration: 300 } );
            
            // expand final to final size, remove old and animated mover
            if ( site == 'serato' ) {
                var mbot = '3';
            } else { 
                var mbot = '0';
            }
            FinalThread.css( { 
                    opacity: 0, height: 0, paddingTop: 0, 
                    paddingBottom: 0, marginBottom: 0 
                } ).animate( {
                    height: '20px', paddingTop: '5px', 
                    paddingBottom: '5px', marginBottom: mbot + 'px' 
                }, { queue: false, duration: 300, complete: function() {
                    OldThread.remove();
                    MovingThread.remove();
                    FinalThread.css( 'opacity', 1 );
                } } 
            );
        }
    }
}

function quickThreadsListUpdate( type ) {
    var ThreadsList = jQuery( '#' + type + ' .threads_list' );
    ThreadsList.fadeTo( 300, 0.8 );
    jQuery( '.list_updated.' + type ).fadeTo( 300, 0.4 )
        .css( 'cursor', 'default' ).unbind( 'click' );
    jQuery.post(
        '/parts/forum/threads/updatedlist', 
        { area_id: areaId, type: type },
        function( updatedList ) {
            var UpdatedThreads = jQuery( updatedList );
            ThreadsList.fadeTo( 600, 0.1, function() {
                ThreadsList.replaceWith( updatedList );
                jQuery( '#' + type + ' .threads_list' )
                    .css( 'opacity', 0.1 ).fadeTo( 600, 1 );
                jQuery( '.list_updated.' + type ).fadeOut( 1000 );
            } );
        }
    );
}

function loadMissingMessages( after, before, allRemaining ) {
    if ( allRemaining ) {
        jQuery( '.unloaded span.loadall' ).text( 'Loading...' );
        jQuery( '.unloaded span.loadsome' ).slideUp( 'fast' );
    } else {
        jQuery( '.unloaded span.loadsome' ).text( 'Loading...' );
        jQuery( '.unloaded span.loadall' ).slideUp( 'fast' );
    }
    
    jQuery( '.unloaded span' )
        .removeClass( 'link' )
        .attr( 'onclick', '' )
        .unbind( 'click' );

    allRemaining = ( allRemaining ) ? 'yes' : 'no';
    
    var msgId = document.location.hash.substring( 1 );
    if ( msgId != '' && !isNaN( msgId ) && !jQuery( '#message_' + msgId ).length ) {
        var mustShow = msgId;
    } else {
        var mustShow = '';
    }

    jQuery.post(
        '/parts/forum/threads/loadfragment',
        { 
            thread_id: threadId, after_id: after, before_id: before, 
            all_remaining: allRemaining, must_show: mustShow
        },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }

            jQuery( '.unloaded' ).slideUp().replaceWith( 
                '<div id="loadedfrom_' + after + '" style="display:none">' +
                Result[1] + '</div>'
            );
            jQuery( '#loadedfrom_' + after ).slideDown( 'normal', function() {
                if ( mustShow ) {
                    jQuery.scrollTo( '#message_' + mustShow, 500, 
                        { easing: 'swing', offset: -20 } );
                }
            } );
                                
            jQuery( 'a[rel^=lightbox]' )
                .slimbox( {}, null, function( el ) {
                    return ( this == el ) || 
                        ( ( this.rel.length > 8 ) && 
                          ( this.rel == el.rel ) );
                } );
        }
    );

}

function showButtons( messageId ) {
    if ( visibleButtons == messageId ) {
        return;
    }

    if ( timeoutedMessage != messageId ) {
        clearTimeout( timeoutId );
        timeoutId = setTimeout( 'reallyShowButtons(' + messageId + ')', 150 );
        timeoutedMessage = messageId;
    }
}

function reallyShowButtons( messageId ) {
	jQuery( '#message_' + visibleButtons + ' .buttons' )
        .not( '.buttons.alwaysvisible' ).fadeOut( 200 );
    jQuery( '#message_' + visibleButtons + ' .buttons.alwaysvisible .forusers .button' )
        .not( '.button.alwaysvisible' ).hide();
    jQuery( '#message_' + visibleButtons + ' .buttons.alwaysvisible .formods .button' )
        .not( '.button.alwaysvisible' ).hide();
    jQuery( '#message_' + visibleButtons + ' .buttons.alwaysvisible .editing .button' )
        .not( '.button.alwaysvisible' ).hide();
    jQuery( '#message_' + visibleButtons + ' .buttons.alwaysvisible .typeswitch .button' )
        .not( '.button.alwaysvisible' ).hide();


    var buttons = jQuery( '#message_' + messageId + ' .buttons' );
	if ( buttons.css( 'display' ) == 'none' ) {
		buttons.fadeIn( 500 );
	} else {
    	buttons.stop().fadeTo( 500, 1 );
	}
    jQuery( '#message_' + messageId + ' .buttons.alwaysvisible .forusers .button' ).show();
    jQuery( '#message_' + messageId + ' .buttons.alwaysvisible .formods .button' )
        .not( '.edit.disabled' ).show();

    if ( jQuery( '#message_' + messageId + ' .edit.disabled' ).length ) {
        jQuery( '#message_' + messageId + ' .buttons.alwaysvisible .editing .button' ).show();
        jQuery( '#message_' + messageId + ' .buttons.alwaysvisible .typeswitch .button' )
            .show();
    }

    visibleButtons = messageId;
}

function showTitleEditButton() {
    if ( jQuery( '#titleeditbutton' ).css( 'display' ) != 'block' ) {
        jQuery( '#titleeditbutton' ).fadeIn( 'fast' );
    }
}

function hideTitleEditButton() {
    if ( jQuery( '#titleeditbutton' ).css( 'display' ) == 'block' ) {
        jQuery( '#titleeditbutton' ).fadeOut( 'fast' );
    }
}

function showTitleEditField() {
    hideTitleEditButton();
    jQuery( '#threadtitle' ).fadeOut( 'fast', function() {
        jQuery( '#titleeditform' ).fadeIn( 'fast' );
        jQuery( '#savecancelbuttons' ).fadeIn( 'fast' );
    } );
}

function cancelTitleEdit() {
    if ( jQuery( '#savecancelbuttons .cancel' ).hasClass( 'disabled' ) ) {
        return;
    }
    jQuery( '#titleeditform input' ).val( jQuery( '#threadtitle' ).html() );
    jQuery( '#titleeditform' ).fadeOut( 'fast', function() {
        jQuery( '#threadtitle' ).fadeIn( 'fast' );
    } );
    jQuery( '#savecancelbuttons' ).fadeOut( 'fast', function() {
        showTitleEditButton();
    } );
}

function saveTitleEdit( threadId ) {
    if ( jQuery( '#savecancelbuttons .save' ).hasClass( 'disabled' ) ) {
        return;
    }

    jQuery( '#savecancelbuttons .save' ).addClass( 'disabled' )
        .text( 'saving...' );
    jQuery( '#savecancelbuttons .cancel' ).addClass( 'disabled' );

    jQuery.post(
        '/parts/forum/threads/edittitle',
        { 
            thread_id: threadId, 
            title: jQuery( '#titleeditform input' ).val()
        },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#threadtitle' ).html( Result[1] );
            jQuery( '#savecancelbuttons .cancel' ).removeClass( 'disabled' );
            jQuery( '#savecancelbuttons .save' ).text( 'Save' ).removeClass( 'disabled' );
            cancelTitleEdit();
        }
    );
}

function isFormFilled( newThread, pm ) {
    var postButtons = jQuery( '#postbuttons input' );
    var complete = false;
    if ( newThread && pm ) {
        complete = ( 
            jQuery( '#postbody' ).val() && 
            jQuery( '#subject' ).val() && 
            jQuery( '#receivers' ).val().length
        );
    } else if ( newThread ) {
        complete = ( jQuery( '#postbody' ).val() && jQuery( '#subject' ).val() );
    } else {
        complete = ( jQuery( '#postbody' ).val() );
    }
        
    postButtons.attr( 'disabled', !complete );
}

function shouting() {
    var body = jQuery( '#postbody' ).val();
    var matches = body.match( /[A-Z]{2,}/g );
    var caps = '';
    
    if ( !matches ) {
        return false;
    }

    for ( i = 0; matches[i]; i++ ) {
        caps += matches[i];
    }

    if ( !caps.length ) {
        return false;
    }

    var matches = body.match( /[a-zA-Z]*/g );
    var allAlpha = '';
    for ( i = 0; matches.length > i; i++ ) {
        allAlpha += matches[i];
    }
    
    return ( caps.length / allAlpha.length ) > 0.5;
}

function previewMessage() {
    if ( shouting() ) {
        jQuery( '#shouting' ).slideDown();
        jQuery( '#shouting .please' ).show();
        if ( !shoutWarned ) {
            shoutWarned = true;
            return;
        }
    } else {
        if ( jQuery( '#shouting' ).css( 'display' ) != 'none' ) {
            jQuery( '#shouting' ).slideUp();
            jQuery( '#shouting .please' ).hide();
            shoutWarned = false;
        }
    }

	// Maybe someone has been *fiddling* with the [quote] and [/quote] tags.
	// Better make sure that we have the same number of each. Otherwise, chaos may ensue.

	var msgBody = jQuery( '#postbody' ).val();
    opening_quote_count = 0;
    closing_quote_count = 0;
	matches = msgBody.match( /\[quote\]/gi );
    if( matches ) opening_quote_count = matches.length;
	matches = msgBody.match( /\[\/quote\]/gi );
    if( matches ) closing_quote_count = matches.length;
	if( opening_quote_count != closing_quote_count ){
		// So, um, now what?
		// I guess we just have to patch things up as best as possible
		if( opening_quote_count > closing_quote_count ){
			// Append additional [/quote] tags to the end of the string
			for( i = 0; i < ( opening_quote_count - closing_quote_count ); i++) msgBody += "\n[/quote]";
		}
		else{
			// Append additional [/quote] tags to the end of the string
			for( i = 0; i < ( closing_quote_count - opening_quote_count ); i++) msgBody = "[quote]\n" + msgBody;
		}
		jQuery( '#postbody' ).val( msgBody );
	}
	
    jQuery( '#postform' ).attr( 'action', '/parts/forum/messages/preview' );
    jQuery( '#postform' ).get( 0 ).submit();
    jQuery( '#postbuttons input' ).attr( 'disabled', true );
    previewTrans = jQuery( '#previewbutton' ).val();
    jQuery( '#previewbutton' ).val( 'loading...' );

    checkForNewMessages();
}

function postMessage() {
    if ( shouting() ) {
        jQuery( '#shouting' ).slideDown();
        if ( !shoutWarned ) {
            jQuery( '#shouting .please' ).show();
            shoutWarned = true;
            return;
        } else {
            jQuery( '#shouting .please' ).hide();
        }
    } else {
        if ( jQuery( '#shouting' ).css( 'display' ) != 'none' ) {
            jQuery( '#shouting' ).slideUp();
            jQuery( '#shouting .please' ).hide();
            shoutWarned = false;
        }
    }
    
    jQuery( '#postform' ).attr( 'action', '/parts/forum/messages/post' );
    jQuery( '#postform' ).get( 0 ).submit();
    jQuery( '#postbuttons input' ).attr( 'disabled', true );
    postTrans = jQuery( '#postbutton' ).val();
    jQuery( '#postbutton' ).val( 'posting...' );

	setTimeout( 'checkIfPostingFailed()', 21000 );
}

function checkIfPostingFailed() {
	if ( postSubmitSuccess ) {
		postSubmitSuccess = false;
		postFailedOnce = false;
		return;
	}
	
	if ( postFailedOnce ) {
		jQuery( '#postingfailed' ).slideDown();
		jQuery( '#postbutton' ).val( postTrans ).blur();
 		isFormFilled();
		postFailedOnce = false;
		return;
	}

	if ( jQuery( '#postbody' ).val().length ) {
    	jQuery( '#postform' ).get( 0 ).submit();
		postFailedOnce = true;
		setTimeout( 'checkIfPostingFailed()', 21000 );
	}
}

function previewThread() {
    jQuery( '#postform' ).attr( 'action', '/parts/forum/threads/preview' );
    jQuery( '#postform' ).get( 0 ).submit();
    jQuery( '#postbuttons input' ).attr( 'disabled', true );
    previewTrans = jQuery( '#previewbutton' ).val();
    jQuery( '#previewbutton' ).val( 'loading...' );
}

function createThread( privateDiscussion ) {
    if ( privateDiscussion ) {
        jQuery( '#postform' ).attr( 'action', '/parts/forum/threads/private/create' );
    } else {
        jQuery( '#postform' ).attr( 'action', '/parts/forum/threads/create' );
    }
    jQuery( '#postform' ).get( 0 ).submit();
    jQuery( '#postbuttons input' ).attr( 'disabled', true );
    postTrans = jQuery( '#postbutton' ).val();
    jQuery( '#postbutton' ).val( 'posting...' );
}

function showPreview( message ) {
	jQuery( '#previewsgohere .message.preview' ).slideUp();
    jQuery( '#previewsgohere' ).append( message );
    jQuery( '.message.preview' )
        .eq( jQuery( '#previewsgohere .message.preview' ).length - 1 )
        .slideDown( "fast", function() {
            // This is a total hack for IE.
            // For some reason the text is not displayed in the post preview 
            // block unless I callthe messageGroup() function. BUT, it only 
            // works correctly if I delay the function call ever so slightly.  
            // WTF? x 1000
            setTimeout( "messageGroup( parseInt( jQuery( '#group_id_read' ).val() ) );", 1 );
        } );
    jQuery( '#postbuttons input' ).attr( 'disabled', false );
    jQuery( '#previewbutton' ).val( previewTrans );
}

function showThreadPreview( threadPreview ) {
    jQuery( '#threadpreviewsgohere .thread_preview' ).slideUp();
    jQuery( '#threadpreviewsgohere' ).append( threadPreview );
    jQuery( '#threadpreviewsgohere .thread_preview' )
        .eq( jQuery( '#threadpreviewsgohere .thread_preview' ).length - 1 )
        .slideDown();
    jQuery( '#postbuttons input' ).attr( 'disabled', false );
    jQuery( '#previewbutton' ).val( previewTrans );
    jQuery( '#postbutton' ).show();
}

function gotoNewThread( threadId ) {
    window.location = '/forum/discussion/' + threadId;
}

function showPost( results ) {
	postSubmitSuccess = true;
    
    if ( results[0] != 'success' ) {
        switch( results[0] ) {
            case 'repost':
                if ( !postFailedOnce ) {
                    alert( 'You have already posted this!' );
                }
                waitingOnPost = false;
                jQuery( '#postbutton' ).val( postTrans ).blur();
                isFormFilled();
                return;
            
            case 'banned':
                alert( 'You no longer have permission to post messages.' );
                waitingOnPost = false;
                return;

            case 'locked':
                alert( 'This discussion is now locked. No new messages can be posted.' );
                return;
            
            default:
                alert( 'Error: ' + results[0] );
                return;
        }
    }

	if ( results[2] == 'tracked' ) {
            jQuery( '#tracklink' )
                .addClass( 'link' )
                .text( 'Stop Tracking This Discussion' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    untrackThread( threadId);
                } );
	}

    waitingOnPost = true;
    checkForNewMessages();
}

function messageGroup( group_id ) {
    jQuery( '.groupidbutton' ).removeClass( 'selected' );
    jQuery( '#postbody' ).attr( 'className', '' );
    switch( group_id ) {
        case 7:
            jQuery( '#modmsgbutton' ).addClass( 'selected' );
            jQuery( '#postbody' ).attr( 'className', 'modmsg' );
            jQuery( '#group_id_read' ).val( '7' );
            break;
        case 0:
            jQuery( '#normalmsgbutton' ).addClass( 'selected' );
            jQuery( '#group_id_read' ).val( '0' );
            break;
        case -1:
            jQuery( '#systemmsgbutton' ).addClass( 'selected' );
            jQuery( '#postbody' ).attr( 'className', 'systemmsg' );
            jQuery( '#group_id_read' ).val( '-1' );
            break;
    }
}

function quoteMessage( messageId ) {
    var msgBody = convertMessageBody( jQuery( '#message_' + messageId + ' .body' ).html() );
    jQuery( '#postbody' ).val( jQuery( '#postbody' ).val() 
        + '[quote]' + msgBody + '[/quote]\n' );
    jQuery.scrollTo( '#postbody', 500, { easing: 'swing' } );
}

function addToPM() {
    if ( jQuery( '#addtopm .button' ).hasClass( 'disabled' ) ) {
        return;
    }
   
    jQuery( '#addtopm .button' ).addClass( 'disabled' );
    jQuery( '#addtopmdialogue' ).fadeIn();
}

function cancelAddToPM() {
    jQuery( '#addtopmdialogue' ).fadeOut( 'fast' );
    jQuery( '#addtopmresults' ).fadeOut( 'fast' );
    jQuery( '#addtopm .button' ).removeClass( 'disabled' );

}

function addThisPersonToPM( userId ) {
    jQuery( '#memberslist' ).animate( { 'opacity': 0.5 } );

    jQuery.post(
        '/parts/forum/threads/addtopm',
        { 
            user_id: userId, thread_id: threadId 
        },
        function( responseText ) { 
			Result = eval( responseText );
            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }

            jQuery( '#memberslist' ).html( Result[1] ).animate( { 'opacity': 1 } );
        }
    );
}

function removeFromPM( userId ) {
    jQuery( '#memberslist' ).animate( { 'opacity': 0.5 } );

    jQuery.post(
        '/parts/forum/threads/removefrompm',
        { 
            user_id: userId, thread_id: threadId 
        },
        function( responseText ) { 
			Result = eval( responseText );
            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }

            jQuery( '#memberslist' ).html( Result[1] ).animate( { 'opacity': 1 } );
        }
    );
}

function searchForUsers( token ) {
    var resultsBox = jQuery( '#addtopmresults' );
    var resultsBoxInner = jQuery( '#addtopmresults .results' );

    if ( !token.length ) {
        resultsBoxInner.text( '' );
        resultsBox.slideUp( 'fast' );
        return;
    }

    if ( token.length == 1 ) {
        return;
    }

    if ( jQuery( '#addtopmresults .results .member' ).length ) {
        resultsBox.slideUp( 'fast', function() {
            resultsBoxInner.html( '<i>Loading...</i>' );
            resultsBox.slideDown( 'fast' );
        } );
    } else {
        resultsBoxInner.html( '<i>Loading...</i>' );
        resultsBox.slideDown( 'fast' );
    }
    
    if ( undefined === window.userSearchOrder ) {
        userSearchOrder = 0;
    }
    userSearchOrder++;

    jQuery.post(
        '/parts/users/pmsearchresults',
        { token: token, order: userSearchOrder },
        function( responseText ) { 
			Result = eval( responseText );
            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            if ( undefined === window.lastSearchReceived ) {
                lastSearchReceived = 0;
            }

            if ( Result[2] < lastSearchReceived ) {
                return;
            }
            lastSearchReceived = Result[2];

            if ( resultsBox.attr( 'display' ) != 'none' ) {
                resultsBox.slideUp( 'fast', function() {
                    jQuery( '#addtopmresults .results' ).html( Result[1] );
                    jQuery( '#addtopmresults' ).slideDown( 'fast' );
                } );
            } else {
                jQuery( '#addtopmresults .results' ).html( Result[1] );
                jQuery( '#addtopmresults' ).slideDown( 'fast' );
            }
        }
    );
}

function showGroupMembers( groupId ) {
    if ( !groupId ) {
        return;
    }
    var resultsBox = jQuery( '#addtopmresults' );
    var resultsBoxInner = jQuery( '#addtopmresults .results' );

    if ( jQuery( '#addtopmresults .results .member' ).length ) {
        resultsBox.slideUp( 'fast', function() {
            resultsBoxInner.html( '<i>Loading...</i>' );
            resultsBox.slideDown( 'fast' );
        } );
    } else {
        resultsBoxInner.html( '<i>Loading...</i>' );
        resultsBox.slideDown( 'fast' );
    }

    jQuery.post(
        '/parts/users/pmsearchresults',
        { group_id: groupId },
        function( responseText ) { 
			Result = eval( responseText );
            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            if ( resultsBox.attr( 'display' ) != 'none' ) {
                resultsBox.slideUp( 'fast', function() {
                    jQuery( '#addtopmresults .results' ).html( Result[1] );
                    jQuery( '#addtopmresults' ).slideDown( 'fast' );
                } );
            } else {
                jQuery( '#addtopmresults .results' ).html( Result[1] );
                jQuery( '#addtopmresults' ).slideDown( 'fast' );
            }
        }
    );
}

function reportMessage( messageId ) {
    if ( jQuery( '#message_' + messageId + ' .button.report' ).hasClass( 'disabled' ) ) {
        return;
    }
    
    if ( jQuery( '#abuse_report_dialog' ).length ) {
        return;
    }
    
    jQuery( 'body > .container' ).append( 
        '<div id="abuse_report_dialog" class="reportbox"><h3>Submit An Abuse Report</h3>' +
        '<p style="padding-top:7px">' +
        '<select style="width:305px" onchange="if (this.value!=0) { jQuery(\'#abuse_report_dialog .additional, #abuse_report_dialog .submit\').fadeIn(\'fast\'); } else { jQuery(\'#abuse_report_dialog .additional, #abuse_report_dialog .submit\').fadeOut(\'fast\'); }">' +
        '<option value="0">-- Reason for reporting this message --</option>' +
        '<option value="1">Breaks rule #1 (Be nice to others)</option>' +
        '<option value="2">Breaks rule #2 (Do not pass yourself off as an employee of Serato or an employee of any Serato business partner)</option>' +
        '<option value="3">Breaks rule #3 (Do not post advertisements for any product or service)</option>' +
        '<option value="illegal">Is illegal, or is organising illegal activities</option>' +
        '<option value="wrongarea">Has been posted in the wrong forum area</option>' +
        '</select></p>' +
        '<span class="additional" style="display:none">' +
        '<p>Do you have any additional comments?</p>' +
        '<textarea></textarea></span>' +
        '<div class="buttons"><span class="link submit" style="display:none" onclick="submitReport(' + messageId + ',this)">Submit</span> <span class="link" onclick="cancelReport()">Cancel</span></div>' );
    var boxTop = ( jQuery( window ).height() / 2 ) - 75;
    jQuery( '#abuse_report_dialog' ).css( 'top', boxTop + 'px' ).fadeIn();
}

function cancelReport() {
    jQuery( '#abuse_report_dialog' ).fadeOut( 
        'normal', function() { jQuery( '#abuse_report_dialog' ).remove(); } 
    );
}

function submitReport( messageId, link ) {
    jQuery( link ).text( 'Submitting...' );
    jQuery.post(
        '/parts/forum/messages/abusereport',
        { 
            message_id: messageId, 
            reason: jQuery( '#abuse_report_dialog select' ).val(),
            comment: jQuery( '#abuse_report_dialog textarea' ).val()
        },
        function( responseText ) { 
			Result = eval( responseText );
            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            cancelReport();
        }
    );
}

function convertMessageBody( msgBody ) {
    // <, > and & character come thru as there respective HTML entites.
    // So strip 'em out
    msgBody = msgBody.replace( /&gt;/gi, ">" );
    msgBody = msgBody.replace( /&lt;/gi, "<" );
    msgBody = msgBody.replace( /&amp;/gi, "&" );
    
    msgBody = msgBody.replace(
        /<div class=("?)quote("?)>[\r\n]*<div class=("?)small("?)><b>Quote:<\/b><\/div>[\r\n]*/gi,
        '[quote]' );
    msgBody = msgBody.replace( /<\/div>[\r\n]*/gi, '[/quote]' );
    // IE strips out line breaks (WTF?)
    // So replace <br> tags with line breaks in IE.
    // For other browsers just strip them out
	msgBody = msgBody.replace( /(<br>|<br\/>)/gi, ( navigator.userAgent.indexOf( "MSIE" ) == -1 ? "" : "\n" ) );
	
    msgBody = msgBody.replace( /<b>/gi, '[b]' );
    msgBody = msgBody.replace( /<\/b>/gi, '[/b]' );
    msgBody = msgBody.replace( /<i>/gi, '[i]' );
    msgBody = msgBody.replace( /<\/i>/gi, '[/i]' );
    msgBody = msgBody.replace( /<u>/gi, '[u]' );
    msgBody = msgBody.replace( /<\/u>/gi, '[/u]' );
    msgBody = msgBody.replace( /<del>/gi, '[s]' );
    msgBody = msgBody.replace( /<\/del>/gi, '[/s]' );

    var matches = msgBody.match( /(<a ([^<]*)<\/a>)/gi );
	
	if( matches ){
		for( i = 0; i < matches.length; i++ ){
			if( matches[i].indexOf( "class=\"media_viewer\"" ) > -1 )
				msgBody = msgBody.replace( matches[i], "" );
			else
				msgBody = msgBody.replace( matches[i], matches[i].match( /<a (?:.*)href="(.*?)"/i )[1] );
		}
	}

    // trim excess whitespace off start and end
    msgBody = msgBody.replace(/^\s+|\s+$/g,"");

    return msgBody;
}

function deleteMessage( messageId ) {
    var button = jQuery( '#message_' + messageId + ' .button.delete' );
    var message = jQuery( '#message_' + messageId );

    if ( button.hasClass( 'disabled' ) ) {
        return;
    }
    
    if ( message.hasClass( 'deleted') ) {
        var undelete = 1;
        button.addClass( 'disabled' ).text( 'undeleting...' );
    } else {
        var undelete = 0;
        button.addClass( 'disabled' ).text( 'deleting...' );
    }
   
    jQuery.post(
        '/parts/forum/messages/delete',
        { message_id: messageId, undelete: undelete },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            button.removeClass( 'disabled' )
            
            if ( undelete ) {
                button.text( 'delete' );
                message.animate( 
                    { 'opacity': 1 }, 200, 'linear', function() {
                        message.removeClass( 'deleted' );
                    }
                );
            } else {           
                button.text( 'undelete' );
                message.animate( 
                    { 'opacity': 0.5 }, 200, 'linear', function() {
                        message.addClass( 'deleted' );
                    }
                );
            }
        }
    );
}

function switchMsgType( button, messageId ) {
    if ( jQuery( button ).hasClass( 'on' ) ) {
        return;
    }

    if ( jQuery( '#message_' + messageId + '.groupmsg' ).length &&
        jQuery( '#message_' + messageId + ' .typeswitch .button.modmsg.on' ).length &&
        !confirm( "Warning! You are choosing to make a moderator message publicly visible! Are you sure that's what you want to do?" ) 
    ) {
        return;
    }

    if ( jQuery( '#message_' + messageId + ' .typeswitch .button.internal.on' ).length ) {
        if ( !confirm( "Warning! You are choosing to make an internal only file downloadable by other users. Please be sure you are selecting the right option. Are you sure you wish to continue?" ) ) {
            return;
        }
    }

    jQuery( '#message_' + messageId + ' .typeswitch .button.on' ).removeClass( 'on' );
    jQuery( button ).addClass( 'on' );

    typeChanged[messageId] = 'yes';   
    jQuery( '#message_' + messageId + ' .button.save' ).removeClass( 'disabled' );
}

function editMessage( messageId ) {
    if ( jQuery( '#message_' + messageId + ' .button.edit' ).hasClass( 'disabled' ) ) {
        return;
    }

    var msgDiv = jQuery( '#message_' + messageId + ' .body' );
    var converted = convertMessageBody( msgDiv.html() );
    
    // save the unedited state for later comparison
    originalMsgBody[messageId] = converted;

    var width = msgDiv.width() ;
    var height = msgDiv.height() - 2;
    if ( navigator.userAgent.indexOf( 'Firefox' ) != -1 ) {
        height = height - 2;
    }

    if ( height < 70 ) {
        height = 70;
    }
    
    msgDiv.fadeOut( 
        'fast',
        function() {
            msgDiv.after(
                '<textarea class="body" style="width:' + width
                + 'px;height:' + height + 'px;margin:0;padding:0;display:none" onkeyup="hasMsgBodyChanged(' 
                + messageId + ')">' + converted + '</textarea>' );
            jQuery( 'textarea.body' ).fadeIn( 'fast' );
            jQuery( '#message_' + messageId + ' .buttons .editing' ).fadeIn( 'fast' );
            jQuery( '#message_' + messageId + ' .buttons .button.edit' )
                .hide().addClass( 'disabled' );
            jQuery( '#message_' + messageId + ' .buttons .typeswitch' ).fadeIn( 'fast' );
            jQuery( '#message_' + messageId + ' .buttons.alwaysvisible .typeswitch .button' )
                .show();
            jQuery( '#message_' + messageId + ' .buttons.alwaysvisible .editing .button' )
                .show();
        }
    );
}

function hasMsgBodyChanged( messageId ) {
    var editedBody = jQuery( '#message_' + messageId + ' textarea' ).val();

    if ( editedBody != originalMsgBody[messageId] || typeChanged[messageId] == 'yes' ) {
        jQuery( '#message_' + messageId + ' .button.save' ).removeClass( 'disabled' );
    } else {
        jQuery( '#message_' + messageId + ' .button.save' ).addClass( 'disabled' );
    }
}

function cancelMessageEdit( messageId ) {
    if ( jQuery( '#message_' + messageId + ' .button.cancel' ).hasClass( 'disabled' ) ) {
        return;
    }

    var msgBodyEdit = jQuery( '#message_' + messageId + ' textarea' )
    
    jQuery( '#message_' + messageId + ' .buttons .editing' ).fadeOut( 'fast' );
    jQuery( '#message_' + messageId + ' .button.edit' ).removeClass( 'disabled' ).show();
    jQuery( '#message_' + messageId + ' .button.save' ).addClass( 'disabled' ).text( 'save' );
    jQuery( '#message_' + messageId + ' .buttons .typeswitch' ).fadeOut( 'fast' );
    
    msgBodyEdit.fadeOut(
        'fast',
        function() {
            jQuery( '#message_' + messageId + ' div.body' ).fadeIn( 'fast' );
            msgBodyEdit.remove();
        }
    );
}

function saveMessageEdit( messageId ) {
    if ( jQuery( '#message_' + messageId + ' .button.save' ).hasClass( 'disabled' ) ) {
        return;
    }

    jQuery( '#message_' + messageId + ' .button.save' ).addClass( 'disabled' )
        .text( 'saving...' );
    jQuery( '#message_' + messageId + ' .button.cancel' ).addClass( 'disabled' );

    var typeButton = jQuery( '#message_' + messageId + ' .typeswitch .button.on' );
    if ( typeButton.hasClass( 'normal' ) ) {
        var type = 'normal';
    } else if ( typeButton.hasClass( 'system' ) ) {
        var type = 'system';
    } else if ( typeButton.hasClass( 'modmsg' ) ) {
        var type = 'modmsg';
    } else if ( typeButton.hasClass( 'all' ) ) {
        var dlType = 'all';
    } else if ( typeButton.hasClass( 'email' ) ) {
        var dlType = 'email';
    } else if ( typeButton.hasClass( 'area' ) ) {
        var dlType = 'area';
    } else if ( typeButton.hasClass( 'internal' ) ) {
        var dlType = 'internal';
    }
   
    jQuery( '#message_' + messageId ).append( 
        '<div class="touch"><span onclick="touch(' + messageId + 
        ')">Click to update message time to now</span> <span onclick="closeTouch(' + 
        messageId + ')">Close</span></div>' );

    jQuery.post(
        '/parts/forum/messages/savebodyedit',
        { 
            message_id: messageId, 
            body: jQuery( '#message_' + messageId + ' textarea' ).val(),
            type: type, download: dlType
        },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#message_' + messageId + ' div.body' ).html( Result[1] );
            jQuery( '#message_' + messageId + ' .button.cancel' ).removeClass( 'disabled' );
            cancelMessageEdit( messageId );

            switch ( type ) {
                case 'normal':
                    jQuery( '#message_' + messageId )
                        .removeClass( 'groupmsg' )
                        .removeClass( 'system' );
                    break;
                case 'system':
                    jQuery( '#message_' + messageId )
                        .removeClass( 'groupmsg' )
                        .addClass( 'system' );
                    break;
                case 'modmsg':
                    jQuery( '#message_' + messageId )
                        .removeClass( 'system' )
                        .addClass( 'groupmsg' );
                    break;
            }
        }
    );
}

function touch( messageId ) {
    var Message = jQuery( '#message_' + messageId );
    var Button = jQuery( '#message_' + messageId + ' .touch' );
    
    if ( Button.hasClass( 'disabled' ) ) {
        return;
    }

    Button.addClass( 'disabled' ).fadeTo( 'normal', 0.4 );

    jQuery.post(
        '/parts/forum/messages/touch',
        { message_id: messageId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }

            Button.fadeOut( 'normal', function() { 
                Button.remove();
                Message.slideUp( 'normal', function() {
                    Message.appendTo( '#messages_list' );
                    jQuery.scrollTo( '#postbox', 500, { 
                            easing: 'swing', 
                            onAfter: function() {
                                Message.slideDown();
                            } 
                        }
                    );
                } );
            } );
        }
    );
}

function closeTouch( messageId ) {
    var Button = jQuery( '#message_' + messageId + ' .touch' );
    Button.fadeOut( 'normal', function() { Button.remove(); } );
}


function markAreaRead( areaId ) {
    jQuery( '.markarearead' )
        .removeClass( 'link' )
        .text( 'Marking discussions...' );
    jQuery.post(
        '/parts/forum/areas/markread',
        { area_id: areaId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '.markarearead' )
                .text( 'All discussions marked as read' )
                .attr( 'onclick', '' );
            jQuery( '.thread .newcounts' ).hide();
            jQuery( '.thread.newmessages' ).animate( {
                'backgroundColor': '#fff',
                'borderBottomColor': '#bbb'
            } );
            if ( site == 'serato' ) {
                jQuery( '.thread .starter' ).animate( { 'color': '#666' } );
                jQuery( '.thread .counts' ).animate( { 'color': '#666' } );
            }
        }
    );
}

function trackThread( threadId ) {
    jQuery( '#tracklink' ).removeClass( 'link' ).text( 'Tracking...' );
    jQuery.post(
        '/parts/forum/threads/track',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#tracklink' )
                .addClass( 'link' )
                .text( 'Stop Tracking This Discussion' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    untrackThread( threadId);
                } );
        }
    );
}

function untrackThread( threadId ) {
    jQuery( '#tracklink' ).removeClass( 'link' ).text( 'Untracking...' );
    jQuery.post(
        '/parts/forum/threads/untrack',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#tracklink' )
                .addClass( 'link' )
                .text( 'Track This Discussion' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    trackThread( threadId);
                } );
        }
    );
}

function markThreadRead( threadId, link ) {
    jQuery( link ).removeClass( 'link' ).text( 'Marking as read...' );
    jQuery.post(
        '/parts/forum/threads/markread',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( link )
                .text( 'Marked as read' )
                .attr( 'onclick', '' );
            
            if ( site == 'serato' ) {
                jQuery( '.message.new:not(.system,.groupmsg)' ).animate( {
                    'backgroundColor': '#fe9',
                    'borderBottomColor': '#bbb'
                } );
                jQuery( '.message.new:not(.system,.groupmsg) .quote' ).animate( {
                    'backgroundColor': '#dc7',
                    'borderTopColor': '#cb6',
                    'borderRightColor': '#cb6',
                    'borderLeftColor': '#cb6',
                    'borderBottomColor': '#ba5'
                } );
                jQuery( '.message.new:not(.system,.groupmsg) .details' ).animate( { 'color': '#666' } );
            } else {
                jQuery( '.message.new:not(.system,.groupmsg)' ).animate( { 'backgroundColor': '#ffd' } );
                jQuery( '.message.new:not(.system,.groupmsg) .quote' ).animate( {
                    'backgroundColor': '#ffc',
                    'borderTopColor': '#666',
                    'borderRightColor': '#666',
                    'borderLeftColor': '#666',
                    'borderBottomColor': '#666'
                } );
            }
        }
    );
}

function markThreadUnread( threadId, link ) {
    jQuery( link ).removeClass( 'link' ).text( 'Marking as unread...' );
    jQuery.post(
        '/parts/forum/threads/markunread',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( link )
                .text( 'Marked as unread' )
                .attr( 'onclick', '' );

            MessagesList.stop().animate( {
                'backgroundColor': '#fb0',
                'borderBottomColor': '#c80'
            }, 1500 );

            jQuery( '.message.new .quote' ).animate( {
                'backgroundColor': '#ea0',
                'borderTopColor': '#e90',
                'borderRightColor': '#e90',
                'borderBottomColor': '#b70',
                'borderLeftColor': '#e90'
            }, 1500 );
        }
    );
}

function lockThread( threadId ) {
    jQuery( '#lockbutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/lock',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#lockbutton' )
                .removeClass( 'loading' )
                .addClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    unlockThread( threadId );
                } );
        }
    );
}

function unlockThread( threadId ) {
    jQuery( '#lockbutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/unlock',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#lockbutton' )
                .removeClass( 'loading' )
                .removeClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    lockThread( threadId );
                } );
        }
    );
}

function hideThread( threadId ) {
    jQuery( '#hidebutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/hide',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#hidebutton' )
                .removeClass( 'loading' )
                .addClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    unhideThread( threadId );
                } );
        }
    );
}

function unhideThread( threadId ) {
    jQuery( '#hidebutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/unhide',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#hidebutton' )
                .removeClass( 'loading' )
                .removeClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    hideThread( threadId );
                } );
        }
    );

}

function hideDeleted() {
    jQuery( '#delbutton' ).attr( 'onclick', '' ).unbind( 'click' );

    if ( !jQuery( '.message.deleted' ).length ) {
        switchButton();
    } else {
        jQuery( '.message.deleted' ).slideUp( 'normal', function() {
            switchButton();
        } );
    }

    function switchButton() {
        jQuery( '#delbutton' ).removeClass( 'on' )
            .attr( 'title', 'Show Deleted Messages' )
            .bind( 'click', function() {
                unhideDeleted();
            } );
    }
}

function unhideDeleted() {
    jQuery( '#delbutton' ).attr( 'onclick', '' ).unbind( 'click' );

    if ( !jQuery( '.message.deleted' ).length ) {
        switchButton();
    } else {
        jQuery( '.message.deleted' ).slideDown( 'normal', function() {
            switchButton();
        } );
    }

    function switchButton() {
        jQuery( '#delbutton' ).addClass( 'on' )
            .attr( 'title', 'Hide Deleted Messages' )
            .bind( 'click', function() {
                hideDeleted();
            } );
    }
}

function makeSticky( threadId ) {
    jQuery( '#stickybutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/sticky',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#stickybutton' )
                .removeClass( 'loading' )
                .addClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    makeUnsticky( threadId );
                } );
        }
    );
}

function makeUnsticky( threadId ) {
    jQuery( '#stickybutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/unsticky',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#stickybutton' )
                .removeClass( 'loading' )
                .removeClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    makeSticky( threadId );
                } );
        }
    );

}

function makeCompulsory( threadId ) {
    jQuery( '#compulsbutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/makecompulsory',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#compulsbutton' )
                .removeClass( 'loading' )
                .addClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    makeNotCompulsory( threadId );
                } );
        }
    );
}

function makeNotCompulsory( threadId ) {
    jQuery( '#compulsbutton' ).addClass( 'loading' );
    jQuery.post(
        '/parts/forum/threads/makenotcompulsory',
        { thread_id: threadId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            jQuery( '#compulsbutton' )
                .removeClass( 'loading' )
                .removeClass( 'on' )
                .attr( 'onclick', '' )
                .unbind( 'click' )
                .bind( 'click', function() {
                    makeCompulsory( threadId );
                } );
        }
    );
}

function showMoveArea() {
    jQuery( '#areas' ).show();
    jQuery( '#move' ).hide();
    jQuery( '#moveareablock br' ).hide();
    jQuery( '#moveareablock .cancel' ).show();
}

function cancelMoveArea() {
    jQuery( '#areas' ).hide();
    jQuery( '#move' ).show();
    jQuery( '#moveareablock br' ).show();
    jQuery( '#moveareablock .cancel' ).hide();
}

function moveArea( currentAreaId, threadId ) {
    var selectedArea = jQuery( '#areas option:selected' );
    var areasSelect = jQuery( '#areas' );
    var areaId = areasSelect.val();
    
    if ( areasSelect.val() == currentAreaId ) {
        return;
    }

    if ( !confirm( 
        "Are you sure you want to move this discussion to the '" 
        + selectedArea.text() + "' area?"
    ) ) {
        areasSelect.val( currentAreaId );
        return;
    }

    jQuery( '#areas option' ).each( function() {
        this.innerHTML = this.innerHTML.replace( /\.+/, '' );
    } );
    areasSelect.css( 'font-style', 'italic' );
    selectedArea.html( selectedArea.html() + '...' );
    
    jQuery.post(
        '/parts/forum/threads/movearea',
        { thread_id: threadId, area_id: areaId },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
            
            history.go( 0 );
        }
    );
}

function showChangeProduct() {
    jQuery( '#products' ).show();
    jQuery( '#changeproduct' ).hide();
    jQuery( '#changeproductblock br' ).hide();
    jQuery( '#changeproductblock .cancel' ).show();
}

function cancelChangeProduct() {
    jQuery( '#products' ).hide();
    jQuery( '#changeproduct' ).show();
    jQuery( '#changeproductblock br' ).show();
    jQuery( '#changeproductblock .cancel' ).hide();
}

function changeProduct( threadId ) {
    var productsSelect = jQuery( '#products' );
    var selectedProduct = jQuery( '#products option:selected' );
    var productName = selectedProduct.val();

    jQuery( '#products option' ).each( function() {
        this.innerHTML = this.innerHTML.replace( /\.+/, '' );
    } );
    productsSelect.css( 'font-style', 'italic' );
    selectedProduct.html( selectedProduct.html() + '...' );
    
    jQuery.post(
        '/parts/forum/threads/changeproduct',
        { thread_id: threadId, product: productName },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
           
            productsSelect.css( 'font-style', 'normal' );
            jQuery( '#products option' ).each( function() {
                this.innerHTML = this.innerHTML.replace( /\.+/, '' );
            } );
            jQuery( '#changeproductblock .product' ).text( productName );
            cancelChangeProduct();
        }
    );
}

function showChangeHardware() {
    jQuery( '#hardware' ).show();
    jQuery( '#changehardware' ).hide();
    jQuery( '#changehardwareblock br' ).hide();
    jQuery( '#changehardwareblock .cancel' ).show();
}

function cancelChangeHardware() {
    jQuery( '#hardware' ).hide();
    jQuery( '#changehardware' ).show();
    jQuery( '#changehardwareblock br' ).show();
    jQuery( '#changehardwareblock .cancel' ).hide();
}

function changeHardware( threadId ) {
    var hardwareSelect = jQuery( '#hardware' );
    var selectedHardware = jQuery( '#hardware option:selected' );
    var hardwareName = selectedHardware.val();


    jQuery( '#hardware option' ).each( function() {
        this.innerHTML = this.innerHTML.replace( /\.+/, '' );
    } );
    hardwareSelect.css( 'font-style', 'italic' );
    selectedHardware.html( selectedHardware.html() + '...' );
    
    jQuery.post(
        '/parts/forum/threads/changehardware',
        { thread_id: threadId, hardware: hardwareName },
        function( responseText ) { 
			Result = eval( responseText );

            if ( Result[0] != 'success' ) {
                alert( 'Error: ' + Result[0] );
                return;
            }
           
            hardwareSelect.css( 'font-style', 'normal' );
            jQuery( '#hardware option' ).each( function() {
                this.innerHTML = this.innerHTML.replace( /\.+/, '' );
            } );
            jQuery( '#changehardwareblock .sethardware' ).text( hardwareName );
            cancelChangeHardware();
        }
    );
}


function showHideToolbox() {
    var inner = jQuery( '#toolbox .inner' );
    if ( inner.css( 'display' ) == 'none' ) {
        inner.slideDown( 150 );
        var state = 'open';
    } else {
        inner.slideUp( 150 );
        var state = 'closed';
    }
    jQuery.post( '/parts/forum/threads/remembertoolboxstate', { state: state } );
}

function collapseGroup( name, title ) {
    var group = jQuery( '#' + name + 'group' );

    jQuery.post( '/parts/forum/grouphide', { group: name, state: 'hide' } );

    group.animate( { 'opacity': 0.5 }, 'fast', 'linear', function() {
        jQuery( title ).find( 'span' ).html( '&#x25b6;' );
        group.slideUp( 'fast', function() {
            group.empty();
			group.parents('.area-container').removeClass('expanded');
			group.parents('.area-container').addClass('collapsed');
        } );
    } );

    jQuery( title ).attr( 'onclick', '' )
        .unbind( 'click' )
        .bind( 'click', function() {
            expandGroup( name, title );
        } );
}

function expandGroup( name, title ) {
    var group = jQuery( '#' + name + 'group' );

    jQuery.post( '/parts/forum/grouphide', { group: name, state: 'show' } );

    if ( !group.children().length ) {
        group.html( '<div style="margin:0 0 14px 20px">Loading...</div>' )
            .hide()
            .css( 'opacity', 1 )
            .slideDown( 100 );

	        jQuery.post(
	            '/parts/forum/areas/getlist',
	                { group: name },
	                function( responseText ) { 
	                Result = eval( responseText );

	                if ( Result[0] != 'success' ) {
	                    alert( 'Error: ' + Result[0] );
	                    return;
	                }
               
	                group.hide()
	                    .html( Result[1] )
	                    .css( 'opacity', 0.5 )
	                    .slideDown( 200, function() {
	                        jQuery( title ).find( 'span' ).html( '&#x25bc;' );

							group.parents('.area-container').removeClass('collapsed');
							group.parents('.area-container').addClass('expanded');

	                        group.animate( { 'opacity': 1 }, 100 );
	                    } );
	            }
	        );

    } else {
        group.slideDown( 200, function() {
            jQuery( title ).find( 'span' ).html( '&#x25bc;' );
            group.animate( { 'opacity': 1 }, 100 );

        } );
    }
    jQuery( title ).attr( 'onclick', '' )
        .unbind( 'click' )
        .bind( 'click', function() {
            collapseGroup( name, title );
        } );
}

function inlineMediaViewer( link_obj, media_type, media_source, domain, id ){
	jQuery( ".inline_media_viewer .header" ).mousedown( function(){ jQuery( ".inline_media_viewer" ).draggable() } );
	jQuery( ".inline_media_viewer .header" ).mouseup( function(){ jQuery( ".inline_media_viewer" ).draggable( "disable" ) } );
	if( parseInt( jQuery.browser.version ) == 6 && jQuery.browser.msie ){
		var topPos = 120 + ( document.body.parentElement ? document.body.parentElement.scrollTop : 0 );
		jQuery( ".inline_media_viewer" ).css( "top", topPos );
	}
	switch( media_type ){
		case "video":
			// Re-write the href tag of the link object so that the browser don't go no where
			link_obj.href = "javascript:void(0);"
			/*
			// Resize would be awesome. But this jQuery plug-in isn't ready for prime time yet.
			// Resize options
			options = {};
			options.aspectRatio = true;
			options.helper = "draggable_proxy";
			options.handles = "se";
			options.autoHide = true;F
			options.minWidth = 520;
			options.minHeight = 360;
			options.ghost = true;
			options.transparent = true;
			options.alsoResize = "#inline_google_viewer .container, #inline_google_viewer object, #inline_google_viewer embed";
			jQuery( "#inline_google_viewer" ).resizable( options );
			*/
			
			jQuery( "#inline_video_viewer .header" ).html( media_source.toUpperCase() + " VIEWER" );
			switch( media_source ){
				case "youtube":
					url = "http://" + domain + "/v/" + id + "&hl=en&fs=1&autoplay=1&enablejsapi=1&playerapiid=inline_video_player";
					break;
				case "vimeo":
					url = "http://vimeo.com/moogaloop.swf?clip_id=" + id + "&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&fullscreen=1&autoplay=1";
					break;
			}
			
			obj = document.getElementById( "inline_video_player" );
			if( obj && obj.loadVideoByUrl ){
				obj.loadVideoByUrl( url ); // youtube is nice
			}
			else{
				if( obj && !obj.loadVideoByUrl ) inlineMediaViewerClose( media_type ); //vimeo is ghey
				var params = { allowScriptAccess: "always" };
				var atts = { id: "inline_video_player" };
				flash_vars = null;
				if( media_source == "vimeo" ){
					flash_vars = {};
					flash_vars.js_api = 1;
					flash_vars.js_swf_id = "inline_video_player";
				}
				swfobject.embedSWF( url, "inline_video_player_placeholder", "500", "310", "8", null, flash_vars, params, atts );
			}
			
			jQuery( "#inline_video_viewer" ).fadeIn();
			
			break;
	}
}

function inlineMediaViewerClose( media_type ){
	obj = document.getElementById( "inline_video_player" );
	if( obj.api_unload ) obj.api_unload(); // vimeo
	if( obj.stopVideo ) obj.stopVideo(); // youtube
	jQuery( ".inline_media_viewer" ).fadeOut();
	jQuery( "#inline_video_viewer .container" ).html( "<div id=\"inline_video_player_placeholder\"></div>" );
}

function attachFile() {
    jQuery( '#attachbox form' ).submit();
    jQuery( '#attachbox .attach' ).fadeOut( 500, function() { 
        jQuery( '#attachbox .attach' )
            .removeClass( 'link' )
            .text( 'Attaching...' )
            .fadeIn( 500 );
    } );
    jQuery( '#attachbox .explain' ).fadeOut( 500, function() {
        jQuery( '#attachbox .explain' )
            .text( 'Your file is uploading. Depending on the file size this may take some time.' )
            .fadeIn( 500 );
    } );
    jQuery( '#attachbox input[type=file]' ).css( 'display', 'none' );
}

function attachFinished( Results ) {
    if ( Results[0] != 'success' ) {
        jQuery( '#attachbox .attach' ).fadeOut( 500, function() { 
            jQuery( '#attachbox .attach' )
                .text( 'Error' )
                .fadeIn( 500 );
        } );
        jQuery( '#attachbox .explain' ).fadeOut( 500, function() {
            jQuery( '#attachbox .explain' )
                .text( Result[0] )
                .fadeIn( 500 );
        } );
        return;
    }

    jQuery( '#attachbox .attach' ).fadeOut( 500, function() { 
        jQuery( '#attachbox .attach' )
            .text( 'Complete' )
            .fadeIn( 500 );
    } );
    jQuery( '#attachbox .explain' ).fadeOut( 500, function() {
        jQuery( '#attachbox .explain' )
            .text( 'Your file has been uploaded and staff have been notified.' )
            .fadeIn( 500 );
	    setTimeout( 'resetAttachForm()', 5000 );
    } );

    checkForNewMessages();
}

function resetAttachForm() {
    jQuery( '#attachbox form' ).get( 0 ).reset();
    jQuery( '#attachbox .attach' ).fadeOut( 500, function() { 
        jQuery( '#attachbox .attach' )
            .addClass( 'link' )
            .text( 'Attach A File' )
            .fadeIn( 500 );
    } );
    jQuery( '#attachbox .explain' ).fadeOut( 500, function() {
        jQuery( '#attachbox .explain' )
            .text( 'Attach a relevant file to this discussion.' )
            .fadeIn( 500 );
    } );
    jQuery( '#attachbox input[type=file]' ).css( 'display', '' );


}

function showHideAttachments() {
    var Attachments = jQuery( '#attachments' );

    if ( Attachments.css( 'display' ) == 'none' ) {
        Attachments.slideDown( 'fast' );
    } else {
        Attachments.slideUp( 'fast' );
    }
}

function positionAttachButton() {
    var link = jQuery( '#attachbox .attach' );
    var right = ( jQuery( '#attachbox' ).width() + 40 ) - 
        ( link.position().left + link.width() + 32 );
    jQuery( '#attachbox input[type=file]' ).css( 'right', right + 'px' );
}

function removePMRecipient( userId ) {
    var receivers = jQuery( '#receivers' ).val().split( ',' );
    var newReceivers = '';
    for ( i = 0; receivers[i]; i++ ) {
        if ( receivers[i] != userId ) {
            newReceivers += receivers[i] + ',';
        }
    }
    newReceivers = newReceivers.replace( /,$/, '' );
    jQuery( '#receivers' ).val( newReceivers );

    jQuery( '#recipient_' + userId ).animate( 
        { width: 'hide', opacity: 0, paddingLeft: 0, paddingRight: 0 }, 400 );
    
    isFormFilled( true, true );
}

function addPMRecipient( recipient ) {
    jQuery( '#addrecipient' ).val( '' );
    
    if ( recipient.length < 2 ) {
        return;
    }
    
    var name = recipient[0];
    var id = recipient[1];
    var userPage = ( recipient[2].length ) ? recipient[2] : 'id:' + id;

    var width = jQuery( '<div class="recipient" id="recipient_' + id + '" style="display:none"><a href="/user/' + userPage + '">' + name + '</a> <span class="link" onclick="removePMRecipient(' + id + ')">x</span></div>' ).appendTo( '#recipients_list' ).width();
    jQuery( '#recipients .recipient:last' )
        .css( { width: 0, opacity: 0, paddingLeft: 0, paddingRight: 0, display: 'block' } )
        .animate( { 
            width: width + 'px', opacity: 1, 
            paddingLeft: '7px', paddingRight: '7px' 
        }, 400 );

    var receiverIds = jQuery( '#receivers' ).val().replace( /,$/, '' );
    jQuery( '#receivers' ).val( receiverIds + ',' + id );

    isFormFilled( true, true );
}

function fadeThread( threadId ) {
    jQuery( '#thread_' + threadId + ' .newcounts' ).hide();
    jQuery( '#thread_' + threadId + ' .prefix' ).hide();
    jQuery( '#thread_' + threadId ).animate( {
        'backgroundColor': '#fff',
        'borderBottomColor': '#bbb'
    }, 600 );
    if ( site == 'serato' ) {
        jQuery( '#thread_' + threadId + ' .starter' ).animate( { 'color': '#666' }, 600 );
        jQuery(  '#thread_' + threadId + ' .counts' ).animate( { 'color': '#666' }, 600 );
    }
}

function showReleaseFeedbackDialog( release_id, message_id, display_name ){
	var boxTop = ( jQuery( window ).height() / 2 ) - 75;
	jQuery( '#release_feedback_dialog .release_id' ).val( release_id );
	jQuery( '#release_feedback_dialog .message_id' ).val( message_id );
	jQuery( '#release_feedback_dialog .display_name' ).html( display_name );
	jQuery( '#release_feedback_dialog textarea' ).val(
						convertMessageBody( jQuery( '#message_' + message_id + ' .body' ).html() )
			  );
	
    jQuery( '#release_feedback_dialog' ).css( 'top', boxTop + 'px' ).fadeIn();
}

function closeReleaseFeedbackDialog(){
	jQuery( '#release_feedback_dialog' ).fadeOut();
}

function submitReleaseDefaultFeedback(){
	if( jQuery( '#release_feedback_dialog textarea' ).val() != '' ){
		jQuery( '#release_feedback_dialog .buttons .submit' ).hide();
		jQuery( '#release_feedback_dialog .buttons .submitting' ).show();
		params = {};
		params.release_id = jQuery( '#release_feedback_dialog .release_id' ).val();
		params.message_id = jQuery( '#release_feedback_dialog .message_id' ).val();
		params.message_text = jQuery( '#release_feedback_dialog textarea' ).val();
		jQuery.post(
			'/parts/releases/savedefaultfeedback',
			params,
			function( responseText ) { 
				Result = eval( responseText );
				if( Result[0] != 'success' ){
					alert( Result[0] );
					return;
				}
				jQuery( '#wl_release_feedback_current .button a' ).attr( 'href', '#' + jQuery( '#release_feedback_dialog .message_id' ).val() );
				jQuery( '#wl_release_feedback_current .poster').html( Result[1] );
				jQuery( '#release_feedback_dialog .poster').html( Result[1] );
				jQuery( '#wl_release_feedback_current .quote_text').html( Result[2] );
				jQuery( '#release_feedback_dialog .quote_text').html( Result[2] );
				jQuery( '#release_feedback_dialog textarea').val( '' );
				jQuery( '#wl_release_feedback_current' ).show();
				jQuery( '#release_feedback_dialog .current' ).show();
				jQuery( '#release_feedback_dialog .buttons .submitting' ).hide();
				jQuery( '#release_feedback_dialog .buttons .submit' ).show();
				closeReleaseFeedbackDialog();
			}
		);
	}
}