var globalHandlers = {
    onLoading: function(){spin()},
    onLoaded: function(){unspin()}
};

Ajax.Responders.register(globalHandlers);

//-------------------------------------------------------------------------------------------------

var dialog = null;

function toggleStar(id) {
    var img = $(id);
    if ( img.src.match(/star_off/)) {
        img.src = '/images/star_on.gif';
    } else {
        img.src = '/images/star_off.gif';
    }
}

function toggleKey(id) {
    var img = $(id);
    if ( img.src.match(/key_off/)) {
        img.src = '/images/key_on.gif';
    } else {
        img.src = '/images/key_off.gif';
    }
}


Position.moveUnder = function(reference, element, resize) {
    resize = resize || false;
    Position.clone(reference, element, {setHeight:false, offsetTop: reference.offsetHeight});
}

function setMessageAndHighlight(element, message)
{
    element.innerHTML = message;
    new Effect.Highlight(element);
}

function getStatusArea(area)
{
    return area ? $(area) : top.document.getElementById('status');
}

function setStatus(message, area)
{
    setMessageAndHighlight(getStatusArea(area), message);
}

function spin(element)
{
    Element.addClassName(document.body, 'waiting');
    if (element) {
        $(element).innerHTML = '<img src="\/images\/spinner.gif" width="16" height="16"\/>';
    }
    else {
        getStatusArea().innerHTML = '';
    }
}

function unspin(element)
{
    Element.removeClassName(document.body, 'waiting');
    if (element)
        $(element).innerHTML = '';
    else
        top.document.getElementById('status').innerHTML = '';
}

function clearStatus()
{
    var statusArea = getStatusArea();
    if (statusArea) // doesn't exist on front page
        statusArea.innerHTML = '';
}

function dialogFromName(name) {
    return $(name+"_dialog");
}

function showDialog(name) {
    //hideAllDialogs();
    dialog = name;
    var dlg = dialogFromName(name);
    if (dlg) dlg.show();
    clearStatus();
}

function clickLoginLink()
{
    showLoginTab();
    showDialog('member');
    focusLoginTab();
    return false;
}

function loginPrompt()
{
    clickSignupLink();
}

function clickSignupLink()
{
    showSignupTab();
    showDialog('member');
    focusSignupTab();
    return false;
}

// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
function getPageSize()
{
    var xScroll, yScroll;

    if (window.innerHeight && window.scrollMaxY) {
        xScroll = document.body.scrollWidth;
        yScroll = window.innerHeight + window.scrollMaxY;
    } else if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac
        xScroll = document.body.scrollWidth;
        yScroll = document.body.scrollHeight;
    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
        xScroll = document.body.offsetWidth;
        yScroll = document.body.offsetHeight;
    }

    var windowWidth, windowHeight;
    if (self.innerHeight) { // all except Explorer
        windowWidth = self.innerWidth;
        windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
        windowWidth = document.documentElement.clientWidth;
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
        windowWidth = document.body.clientWidth;
        windowHeight = document.body.clientHeight;
    }

    // for small pages with total height less then height of the viewport
    if (yScroll < windowHeight){
        pageHeight = windowHeight;
    } else {
        pageHeight = yScroll;
    }

    // for small pages with total width less then width of the viewport
    if(xScroll < windowWidth){
        pageWidth = windowWidth;
    } else {
        pageWidth = xScroll;
    }

    arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
    return arrayPageSize;
}

function showOverlay()
{
    var overlay = document.createElement('div');
    overlay.id = "overlay";
    fillScreen(overlay);
    document.body.appendChild(overlay);
}
function fillScreen1(overlay) {
    var arrayPageSize = getPageSize();
    overlay.style.width = (arrayPageSize[0] + 'px');
    overlay.style.height = (arrayPageSize[1] + 'px');

    var screenWidth = window.screen.width;

    if (document.body.clientWidth)
        screenWidth = document.body.clientWidth;
    else if (window.innerWidth)
        screenWidth = window.innerWidth;
}

function hideOverlay()
{
    Element.remove('overlay');
}

function validateSignupForm(signupForm)
{
    if (signupForm.signup_user_name.value.length == 0)
    {
        alert('That doesn\'t look like a name to me...')
        signupForm.signup_user_name.focus();
        return false;
    }
    var regEx = /^[\w\d][_\.\-\w\d+]*@[\w\d][\.\-\w\d]*\.\w{2,}$/
    if (!signupForm.signup_user_email_address.value || !signupForm.signup_user_email_address.value.match(regEx))
    {
        alert('That is not a valid email address.  What\'re you trying to pull?')
        signupForm.signup_user_email_address.focus();
        return false;
    }

    if (signupForm.signup_user_password.value.length < 4)
    {
        alert('Dude, passwords must be at least 4 characters long.  You don\'t want someone stealing your account.');
        signupForm.signup_user_password.focus();
        return false;
    }
}

function validateLoginForm(loginForm)
{
    if (!loginForm.login_user_email_address.value)
    {
        alert('You forgot to enter an email address.')
        loginForm.login_user_email_address.focus();
        return false;
    }

    if (!loginForm.login_user_password.value)
    {
        alert('You forgot to enter a password.')
        loginForm.login_user_password.focus();
        return false;
    }
}

function keepPositionOnscreen(position, dimensions) {
    var x = Math.min(document.body.offsetWidth-dimensions['width']-24, Math.max(position[0], 0));
    var y = Math.min(document.body.offsetHeight-dimensions['height'], Math.max(position[1], 0));
//    var y = Math.min(getWindowHeight()+document.body.scrollTop-dimensions['height'], Math.max(position[1], 0));
//    setStatus(document.body.scrollTop);
    return [x,y];
}

function moveUnder(idMove, idUnder)
{
    var under = $(idUnder);
    var move = $(idMove);
    
    var moveDimensions = Element.getDimensions(move);

    var refPosition = Position.cumulativeOffset(under);
    var newPosition = [refPosition[0], refPosition[1]+under.offsetHeight];
    
    newPosition = keepPositionOnscreen(newPosition, moveDimensions);
    move.setStyle({left: newPosition[0]+"px", top: newPosition[1]+"px"});

/*    var underOffset = Position.cumulativeOffset($(idUnder));
    var underOnLeft = underOffset[0] < document.body.offsetWidth / 2;
    var moveWidth = Element.getDimensions(idMove)["width"];
    $(idMove).style.left = (underOnLeft ? underOffset[0] : (underOffset[0] - moveWidth + 10)) + "px";
    $(idMove).style.top = underOffset[1] + Element.getHeight($(idUnder)) + "px";
    */
}

function moveOver(box, tag, title)
{
    box.style.left = Position.cumulativeOffset(tag)[0] + Position.cumulativeOffset(title)[0] + Position.cumulativeOffset(box)[0] - 2 + "px";
    box.style.top = Position.cumulativeOffset(tag)[1] - Position.cumulativeOffset(title)[1] + Position.cumulativeOffset(box)[1] - 2 + "px";
}

function hideAllDialogs()
{
    if ($('add_tag_dialog'))
        Element.hide('add_tag_dialog');
    /*
    try {
        var elements = $$('.subdialog')
        elements.each(function(e) {Element.hide(e)});
    } catch(exception) {
    }
    */
}

function hide(element)
{
    if ($(element))
        Element.hide(element);
}

function hideIfEqual(element, ifEqualToElement, dialogName)
{
    if (element == ifEqualToElement && Element.visible(dialogName))
        hideAllDialogs();
    else
    {
        hideAllDialogs();
        Element.show(dialogName);
    }
}

var showTagDialogSource = null;
function showAddTagDialog(name, id, clickedElement)
{
    moveUnder('add_tag_dialog', clickedElement);
    hideIfEqual(clickedElement, showTagDialogSource, 'add_tag_dialog');
    showTagDialogSource = clickedElement;
    
    $('add_tag_target_user_id').value = id;
    $('add_tag').value = '';
    $('add_tag').focus();
}

function showFeedbackDialog(clickedElement)
{
    if (Element.visible(dialogFromName('feedback'))) return;
    showDialog('feedback');
    moveUnder('feedback_dialog', clickedElement);
    $('feedback_body').focus();
}

function showVoteTagDialog(clickedElement, tagId, tagName, htmlLinkTo, userName, userTaggingId, profileId, isTagOnSelf, x, y)
{
    if (isTagOnSelf)
        Element.hide('vote_tag_add_to_me');
    else
        Element.show('vote_tag_add_to_me');

    Element.show('vote_tag_latest_votes');
    $('vote_tag_id').value = tagId;
    $('my_vote_tag_id').value = tagId;

    $('vote_target_profile_id').value = profileId;

    Element.hide('vote_tag_vote');
    Element.hide('vote_tag_voters');
    Element.hide('my_vote_tag')
    Element.show('vote_tag_neg');
    Element.show('vote_tag_pos');

    $('vote_tag_voters_list').innerHTML = '';
    $('my_vote_tag_current').innerHTML = '';
    
    $('vote_tag_tag_name').innerHTML = htmlLinkTo;
    $('my_vote_tag_tag_name').innerHTML = htmlLinkTo;

    $('vote_tag_user_tagging_id').value = userTaggingId;
    $('my_vote_tag_user_tagging_id').value = 'me';
    
    // Admin
    if ($('vote_rename_tag_id'))
    {
        $('vote_rename_tag_id').value = tagId;
        if ($('vote_clone_tag_id'))
            $('vote_clone_tag_id').value = tagId;
        if ($('vote_delete_tag_id'))
            $('vote_delete_tag_id').value = tagId;
        if ($('vote_rename_new_tag_name'))
            $('vote_rename_new_tag_name').value = tagName;
    }
    
    var box = $('vote_tag_dialog');

    Event.observe(box, 'mouseover', function(event) {
        Event.stop(event);
    }, true);

    var boxWidth = Element.getDimensions(box)['width'];

    // TODO: The -24 is arbitrary, but seems to work.  Get a real number in here.

    box.setStyle({
        left: Math.max(0, Math.min(x - boxWidth/2, getWindowWidth()-boxWidth-24))+"px",
        top: Math.max(0, y - 10) +"px"});
    
    showDialog('vote_tag');

    new Ajax.Request('/do/voting/update_vote_dialog', {
        asynchronous:true, 
        evalScripts:true, 
        parameters:"user_tagging_id="+userTaggingId+"&tag_id="+tagId,
        onLoading: function(){spin('vote_tag_current')},
        onLoaded: function(){unspin('vote_tag_current')}
        });
}

function voteTagDialogShowAddToMe()
{
    Element.hide('vote_tag_voters');
    Element.hide('my_vote_tag_vote');
    Element.toggle("my_vote_tag");
    if ($('my_vote_tag_current').innerHTML == '' && Element.visible("my_vote_tag"))
    {
        new Ajax.Request('/do/voting/update_add_to_me', {
            onLoading: function(){spin('my_vote_tag_current')},
            onLoaded: function(){unspin('my_vote_tag_current')},
            asynchronous:true,
            evalScripts:true, parameters:"tag_id="+$('vote_tag_id').value});
    }
}

function retractVote(userTaggingIdDivId, removeVoteUrl)
{
    new Ajax.Request(removeVoteUrl, {
        asynchronous:true, 
        evalScripts:true, 
        parameters:"user_tagging_id="+$(userTaggingIdDivId).value+"&last_location="+$('last_location').value,
        onLoading:function(){spin()},
        onLoaded:function(){unspin()}
        });
    Element.hide('vote_tag_dialog');        
}

function redirectIfOnTop(url)
{
    if (window == window.top)
        top.location.href = url;
}

function getElementsByClassName(oElm, strTagName, oClassNames)
{
    /*
        Written by Jonathan Snook, http://www.snook.ca/jonathan
        Add-ons by Robert Nyman, http://www.robertnyman.com
    */
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    var arrRegExpClassNames = new Array();
    if(typeof oClassNames == "object")
    {
        for(var i=0; i<oClassNames.length; i++)
        {
            arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
        }
    }
    else
    {
        arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
    }
    var oElement;
    var bMatchesAll;
    for(var j=0; j<arrElements.length; j++)
    {
        oElement = arrElements[j];
        bMatchesAll = true;
        for(var k=0; k<arrRegExpClassNames.length; k++)
        {
            if(!arrRegExpClassNames[k].test(oElement.className))
            {
                bMatchesAll = false;
                break;                      
            }
        }
        if(bMatchesAll)
        {
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements)
}

function hideElements(classToHide)
{
    array = getElementsByClassName(document, '*', classToHide)
    for (var i = 0; i < array.length; ++i)
        Element.hide(array[i])
}

function addAutocorrectItemToList(tryHidden, didHidden, search, selectedItem)
{
    if (!selectedItem.innerHTML)
        return;

    var searchBox = $(search);
    var currentSearch = searchBox.value;
    var lastCommaIndex = currentSearch.lastIndexOf(',');
    var prefixStartIndex = lastCommaIndex > 0 ? (lastCommaIndex + 1) : 0;
    var prefix = currentSearch.substring(prefixStartIndex, currentSearch.length)
    
    var tryField = $(tryHidden);
    var didField = $(didHidden);
    if (prefix != selectedItem.innerHTML && didField.value.length < 50 && tryField.value.length < 50)
    {
        if (tryField.value != '')
        {
            tryField.value += ',';
            didField.value += ',';
        }
        tryField.value += prefix;
        didField.value += selectedItem.innerHTML.unescapeHTML();
    }

    searchBox.value = currentSearch.substring(0, prefixStartIndex) + selectedItem.innerHTML.unescapeHTML();
    searchBox.focus();
}

function toggleFocus(toggleElem, focusElem)
{
    Element.toggle(toggleElem)
    if (Element.visible(toggleElem))
        $(focusElem).focus();
}

function submitAddTagForm(add_tag_url, form)
{
    new Ajax.Request(add_tag_url,
                     {asynchronous:true, evalScripts:true,
                      onLoaded:function(request){unspin()},
                      onLoading:function(request){spin()},
                      parameters:Form.serialize(form)});
    return false;
}

function getDomainName(url) {
    if (url == '' || url == null) {
        return url;
    }
    var matches = url.match( /:\/\/(www\.)?([^\/:]+)/, '$2');
    if (matches) {
        return matches[2];
    } else {
        return url;
    }
}

function loadFavicon(url, element) {
    if (element.loaded) return;
    
    var known = {
        'friendster.com':'http://images.friendster.com/images/friendster2.ico',
        'evite.com':'http://evite.com/images/favicon.ico'        
    }
    
    var domain = getDomainName(url);
    var src = known[domain];
    if (src) {
        element.loaded = true;
        element.src = src;
    } else {
        var base = 'http://' + url.replace(/^(http:\/\/)?([^/]+).*/, '$2') + '/';
        var names = ['favicon.ico', 'favicon.gif'];
        names.each(function(name) {
            var img = new Image();
            img.onload = function() {
                if (!element.loaded) {
                    element.loaded = true;
                    element.src = img.src;
                }
            }
            img.src = base + name;
        });
    }
}

// convert from [0,100] to age range
function sliderNumberStretch(value)
{
    return 10.5*Math.exp(0.02*value)+2;
}

// convert from age range to [0,100]
function sliderNumberUnstretch(value)
{
    return Math.log((value-2)/10.5)/0.02;
}

var ageSlider = null;
function initAgeSearchSlider(ageLowLimit, ageHighLimit, ageFrom, ageTo)
{
    var ageHandles = ['age_slider_handle_1', 'age_slider_handle_2'];
    var ageValues = [0, 100];
    var initializing = true;
    
    // track which slider changes so we highlight the right value
    var sliding = false, beginSlideFrom, beginSlideTo;
    
    ageHandles.each( function(ageHandle) { setHandCursorStyle(ageHandle); });
    ageSlider = new Control.Slider(ageHandles, 'age_slider_track',
    {
        range: $R(ageValues[0], ageValues[1], false /*exclusive*/),
        restricted: true,
        sliderValue: ageValues,
        onChange: function(v)
        {
            if (initializing)
                return;
            ageHandles.each( function(ageHandle) { setHandCursorStyle(ageHandle); });
            updateAgeSliderText(ageLowLimit, ageHighLimit, Math.floor(v[0]), Math.ceil(v[1]));
            if (sliding)
            {
                // only highlight the value that changed from when the slide began
                if (beginSlideFrom != $('age_from').value)
                {
                    highlightSliderText($('age_from_text'));
                    beginSlideFrom = $('age_from').value
                }
                if (beginSlideTo != $('age_to').value)
                {
                    highlightSliderText($('age_to_text'));
                    beginSlideTo = $('age_to').value
                }
                sliding = false;
            }
        },
        onSlide: function(v)
        {
            ageHandles.each( function(ageHandle) { setClosedHandCursorStyle(ageHandle); });
            updateAgeSliderText(ageLowLimit, ageHighLimit, Math.floor(v[0]), Math.ceil(v[1]));
            if (!sliding)
            {
                // record what the values are when we begin a slide
                beginSlideFrom = $('age_from').value
                beginSlideTo = $('age_to').value
                sliding = true;
            }
        }
    });
    setAgeSliderValues(ageLowLimit, ageHighLimit, ageFrom, ageTo)
    initializing = false;
}

function updateAgeSliderText(ageLowLimit, ageHighLimit, newAgeFrom, newAgeTo)
{
    newAgeFrom = Math.floor(sliderNumberStretch(newAgeFrom));
    newAgeTo = Math.ceil(sliderNumberStretch(newAgeTo));
    
    var newAgeFromHtml = (newAgeFrom <= ageLowLimit ? ageLowLimit : newAgeFrom);
    var newAgeToHtml = (newAgeTo >= ageHighLimit ? ageHighLimit : newAgeTo);
    var linkWord = 'to';
    
    var tooOld = newAgeTo >= ageHighLimit;
    var tooYoung = newAgeFrom <= ageLowLimit;
    
    if (tooOld && tooYoung)
    {
        newAgeFromHtml = '';
        linkWord = 'don\'t matter';
        newAgeToHtml = '';
    }
    else if (tooOld)
    {
        linkWord = 'and';
        newAgeToHtml = 'up';
    }
    else if (tooYoung)
    {
        newAgeFromHtml = 'up';
    }

    $('ageLinkWord').innerHTML = linkWord;
    updateSliderText(newAgeFrom, newAgeFromHtml, $('age_from_text'), $('age_from'));
    updateSliderText(newAgeTo, newAgeToHtml, $('age_to_text'), $('age_to'));
    updateMask();
}

function updateMask()
{
    var leftMask = $('left_mask');
    var rightMask = $('right_mask');
    
    // handle1Left doesn't have a left style in IE before it's started sliding.
    var handle1Left = $('age_slider_handle_1').style.left;
    if (handle1Left)
        leftMask.style.width = handle1Left;
    
    var handle2Left = $('age_slider_handle_2').style.left
    if (handle2Left)
        rightMask.style.width = (180 - parseInt(handle2Left))+"px";
}

function resetAdvancedFilters(defaultLocation, ageLowLimit, ageHighLimit)
{
    $('name').value = '';
    $('tag').value = '';
    $('location').value = defaultLocation;
    $('require_picture_checkbox').checked = false;
    $('gender_b').checked = true;
    
    var trusted_contacts_filter = $('trusted_contact_filter');
    if(trusted_contacts_filter)
        trusted_contacts_filter.checked = false;
    
    setAgeSliderValues(ageLowLimit, ageHighLimit, ageLowLimit, ageHighLimit);
}

function setAgeSliderValues(ageLowLimit, ageHighLimit, ageFrom, ageTo)
{
    ageSlider.setValue(Math.floor(sliderNumberUnstretch(ageFrom-0.4)), 0);
    ageSlider.setValue(Math.ceil(sliderNumberUnstretch(ageTo)), 1);
    updateAgeSliderText(ageLowLimit, ageHighLimit, sliderNumberUnstretch(ageFrom), sliderNumberUnstretch(ageTo));
}

var ageSearchSliderInitialized = false;
function tryInitializeSlider(ageLowLimit, ageHighLimit, ageFrom, ageTo)
{
    if (ageSearchSliderInitialized)
        return;
    initAgeSearchSlider(ageLowLimit, ageHighLimit, ageFrom, ageTo);
    //ageSearchSliderInitialized = true;
}

function toggleAdvancedSearch(ageLowLimit, ageHighLimit, ageFrom, ageTo, defaultLocation)
{
    if (Element.visible("advanced_search"))
    {
        filteredLocation = $('location').value == defaultLocation ? '' : $('location').value
        $('search').value = [$('name').value, $('tag').value, filteredLocation].reject(function(value, index) {return value==""}).join(' ')
        resetAdvancedFilters(defaultLocation, ageLowLimit, ageHighLimit);
        Element.hide('advanced_search');
        Element.show('basic_search');
        $('search').focus();
    }
    else
    {
        setTimeout(function(){tryInitializeSlider(ageLowLimit, ageHighLimit, ageFrom, ageTo);}, 100);
        $('search').value = '';
        Element.show('advanced_search');
        Element.hide('basic_search');
        $('name').focus();
    }
    setFooter();
}

function updateSliderText(newVal, newHtmlVal, textElement, hiddenElement)
{
    hiddenElement.value = newVal;
    textElement.innerHTML = newHtmlVal;
}

function highlightSliderText(div)
{
    new Effect.Highlight(div, {startcolor:'#0ca5dd', endcolor:'#d5eaf2'});
}