var noCacheRand = Math.floor(Math.random()*999999);

function ajaxFailure(req) {
    try {
        if (!isECMA(req)) {
            document.body.innerHTML = req.responseText;
            return;
        }
        var resp = eval('('+req.responseText+')');
        $('errorDesc').innerHTML = "There was an error in the response from the server.<br/>"+
                                   "Refresh the page before posting more comments.<br/>"+
                                   "Click 'show details' for more information.";
        $('showErrorDetails').style.display = "";
        if (resp.errorMsg) {
            $('errorResponse').innerHTML = resp.errorMsg;
        }
        showErrorBox();
    } catch (e) {
        displayErrorInResponse(e);
    }

}

function checkError(resp){
    if(resp.error){
        window.alert(resp.errorHtml);
        return true;
    }
    return false;
}
function showErrorBox(){
    center('errorBox');
    return false;
}

function hideErrorBox(){
    $("errorDetails").style.display = "none";
    $('errorBox').style.display ="none";
    return false;
}

function center(element){
    try{
        element = $(element);
    }catch(e){
        return;
    }

    var my_width  = 0;
    var my_height = 0;

    if ( typeof( window.innerWidth ) == 'number' ){
        my_width  = window.innerWidth;
        my_height = window.innerHeight;
    }else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ){
        my_width  = document.documentElement.clientWidth;
        my_height = document.documentElement.clientHeight;
    }
    else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ){
        my_width  = document.body.clientWidth;
        my_height = document.body.clientHeight;
    }

    element.style.position = 'absolute';
    element.style.zIndex   = 99;

    var scrollY = 0;

    if ( document.documentElement && document.documentElement.scrollTop ){
        scrollY = document.documentElement.scrollTop;
    }else if ( document.body && document.body.scrollTop ){
        scrollY = document.body.scrollTop;
    }else if ( window.pageYOffset ){
        scrollY = window.pageYOffset;
    }else if ( window.scrollY ){
        scrollY = window.scrollY;
    }

    var elementDimensions = Element.getDimensions(element);

    var setX = ( my_width  - elementDimensions.width  ) / 2;
    var setY = ( my_height - elementDimensions.height ) / 2 + scrollY;

    setX = ( setX < 0 ) ? 0 : setX;
    setY = ( setY < 0 ) ? 0 : setY;

    element.style.left = setX + "px";
    element.style.top  = setY + "px";

    element.style.display  = 'block';
}

function isECMA(req){
    return req.getResponseHeader("Content-Type").match(/^application\/ecmascript/);
}
function isHTML(req){
    return req.getResponseHeader("Content-Type").match(/^text\/html/);
}
function isHTMLFrag(req){
    return !req.responseText.match(/<body/i);
}
function displayUnexpectedResponse(req){
    if(isHTML(req)){
        if(isHTMLFrag(req)){
            $('errorDesc').innerHTML = "There was an unexpected response to your action. Click 'show details' to see the response";
            $('showErrorDetails').style.display = "";
            $('errorResponse').innerHTML = req.responseText;
            showErrorBox();
        } else {
            window.location.reload();
        }
    }
}
function displayErrorInResponse(err){
    $('errorDesc').innerHTML = "There was an error in the response from the server.<br/>"+
                               "Refresh the page before posting more comments.<br/>"+
                               "Click 'show details' for more information.";
    $('showErrorDetails').style.display = "";
    $('errorResponse').innerHTML = err;
    showErrorBox();
}

function ajaxDo(url, params, onCompleteFunc){
    ajaxUpdate(url, params, null, onCompleteFunc);
}

function ajaxUpdate(url, params, elementToUpdate, onCompleteFunc){

    var done = function(req) {
        try{
            if(!isECMA(req)){
                displayUnexpectedResponse(req);
                return;
            }
            var resp = eval('('+req.responseText+')');
            if(!resp.worked){
                $('errorDesc').innerHTML = resp.errorMsg;
                showErrorBox();
            } else if(elementToUpdate){
                $(elementToUpdate).innerHTML = resp.payload;
                setTimeout(function() {resp.payload.evalScripts()}, 100);
            }
            if (onCompleteFunc) {
                onCompleteFunc(resp);
            }
        }catch (e){
            displayErrorInResponse(e);
            if (onCompleteFunc) {
                onCompleteFunc({ worked: false });  //allow function to clean up
            }
        }
    };
    var myAjax = new Ajax.Request(url, {parameters: params, onSuccess: done, onFailure: ajaxFailure});
    return false;
}

function updateFrxFromRev(permaId, frxId) {
    var oldInnerHTML = $('frxouter'+frxId).innerHTML;
    startSpin('frxinner'+frxId, true);
    var form = $('updateFrxFromForm'+frxId);
    var url = fishEyePageContext + '/json/cru/' + permaId + '/updateFromRevAjax';
    var pars = getFormPars(form);
    var dest = $('frxouter' + frxId);
    var onComp = function(origRequest) {
        if (!origRequest.worked){
            // if the request didn't work, make sure the spinner
            // is taken out, and the old text restored.
            $('frxouter'+frxId).innerHTML = oldInnerHTML;
        }
        toggleNodeAndImage('changeDiffButton'+frxId, true, false, true);
    }
    ajaxUpdate(url,pars,dest,onComp);
    return false;
}

function toggleSourceType(permaId, frxId, showAnnotation, params) {
    startSpin('sourcefrxinner'+frxId,true);
    var dest = $('frxinner'+frxId);
    var url = fishEyePageContext + '/json/cru/' + permaId + '/toggleSourceTypeAjax';
    var showAnnotationStr = '';
    var dof = $('diffOptionsForm');
    var onComp = function(origRequest) {
        setCommentWidths(null, true);
    }
    if(showAnnotation) {
        showAnnotationStr = '&showAnnotation=true'
        if(dof){
            dof.style.display = 'none';
        }
    } else {
        if(dof){
            dof.style.display = '';
        }
    }

    var pars = 'frxid=' + frxId + showAnnotationStr + params;
    ajaxUpdate(url,pars,dest,onComp);
    return false;
}

var frxDiffMap = $H();

function postEditDetailsForm(reloadPage) {
    var url = fishEyePageContext + '/json/cru/' + permaId + '/postDetails';
    var params = Form.serialize(document.forms.editDetailsForm);

    if (reloadPage) {
        params = params + '&command=norender';
        ajaxDo(url, params, reloadPage);
    } else {
        startSpin('detailsSpinner',false);
        var dest = $('reviewInfo');
        params = params + '&command=update';
        ajaxUpdate(url, params, 'reviewInfo');
    }
    return false;
}

function postLinkedReview() {
    var url = fishEyePageContext + '/json/cru/' + permaId + '/linkReview';
    var newParentId = document.linkReviewForm.parentReviewId.value;

    var params = '&parentReviewId=' + newParentId;

    ajaxUpdate(url, params, 'linkReview');

}

function postUnlinkReview() {
    var url = fishEyePageContext + '/json/cru/' + permaId + '/linkReview';

    var params = '&unlinkParent=true'

    ajaxUpdate(url, params, 'linkReview');
}

function frxLoadDiff(frxId, onCompleteFunc) {
    if (!frxDiffMap[frxId]) {
        startSpin('frxDisplayDiff'+frxId,true);
        var dest = $('frxinner'+frxId);
        var url = fishEyePageContext + '/json/cru/' + permaId + '/loadFrxAjax';
        var pars = 'frxid=' + frxId + '&dontCache=' + noCacheRand;
        frxDiffMap[frxId] = true;
        ajaxUpdate(url,pars,dest, onCompleteFunc);
    } else {
        if (onCompleteFunc) {
            onCompleteFunc();
        }
    }
}

function frxLoadAsyncDiff(i, frxIds) {

    if ((i < frxIds.length) && (i < 100)) { // load and chain
        var frxId = frxIds[i];
        var onComp = function(origRequest) {
            frxLoadAsyncDiff(i + 1, frxIds); // chain
            setCommentWidths();
        }
        frxLoadDiff(frxId, onComp); // load
    } else { // when finished chaining
        if (postPostLoadFunc) {
            postPostLoadFunc();
        }
        if ($("rightBarControls_1")) {
            $("rightBarControls_1").disabled = false;
            simpleSwapInline("show_source_button_disabled","show_source_button");
            simpleSwapInline("show_commit_msg_button_disabled","show_commit_msg_button");
        }
    }
}

function frxLazyLoad(frxArray) {
    frxLoadAsyncDiff(0, frxArray);
}

function publishComment(commentId, permaId){
    var url = fishEyePageContext + '/json/cru/' + permaId + '/publishCommentAjax/';
    var params  = "commentId="+commentId;
    var done = function(resp) {
        if(resp.worked){
            modifyIndicatorDisplay("draftIndicator",commentId,"none");
            modifyIndicatorDisplay("draftPublish",commentId,"none");
            commentList[commentId].draft = false; //todo might be better to resync from the server?
            updateCommentCount(resp.value);
        }
    };
    ajaxDo(url,params,done);
    return false;

}

function deleteComment(commentId, permaId){
    var url = fishEyePageContext + '/json/cru/'+permaId+'/deleteCommentAjax/';
    var params  = "commentId="+commentId;
    var done = function(resp) {
        if(resp.worked){
            //turn off all displayed comments with comment ID
            deleteComments("comment",commentId);
            deleteComments("reply",commentId);
            updateCommentCount(resp.value);
        }
    };
    ajaxDo(url,params,done);
    return false;
}

function addRevisionComment(permaId, form, draft) {
    commentLock = true;
    startSpin(form.parentNode);
    var url = fishEyePageContext + '/json/cru/' + permaId + '/revisionCommentAjax/';
    var params  = getFormPars(form)+"&draft="+(draft ? draft : false);
    var done = function(resp) {
        stopSpin(form.parentNode);
        insertRevisionComment(resp); //checks worked
        commentLock = false;
    };
    ajaxDo(url, params, done);
    return false;
}

function addReply(permaId, form, draft) {
    startSpin(form.parentNode);
    commentLock = true;
    var url = fishEyePageContext + '/json/cru/' + permaId + '/replyAjax/';
    var params  = getFormPars(form)+"&draft="+(draft ? draft : false);
    var done = function(resp) {
        stopSpin(form.parentNode);
        insertAjaxReply(resp); //checks worked
        commentLock = false;
    };
    ajaxDo(url, params, done);
    return false;
}

function addGeneralComment(permaId, form, draft) {
    startSpin(form.parentNode);
    commentLock = true;
    var url = fishEyePageContext + '/json/cru/' + permaId + '/iterationCommentAjax/';
    var params  = getFormPars(form)+"&draft="+(draft ? draft : false);
    var done = function(resp) {
        stopSpin(form.parentNode);
        insertAjaxGeneralComment(resp); //checks worked
        commentLock = false;
    };
    ajaxDo(url, params, done);
    return false;
}

function markFRXComplete(frxId, complete){
    var url = fishEyePageContext + '/json/cru/' + permaId + '/completeFRXAjax/';
    var params  = "frxId="+frxId+"&complete="+complete;

    $('notDone'+frxId).style.display = "none";
    $('done'+frxId).style.display = "none";
    $('busy'+frxId).style.display = "inline";

    var done = function(resp) {
        $('busy'+frxId).style.display = "none";
        if(resp.value == 1){
            $('done'+frxId).style.display = "inline";
            collapseBasic("frxinner" + frxId);
        } else {
            $('notDone'+frxId).style.display = "inline";
        }

    };
    ajaxDo(url,params,done);
    return false;
}


function getFormPars(form){
    return Form.serialize(form);
}

function startSpin(id, Replace, tagType){
    var el = $(id);
    var tag = tagType ? tagType : 'div'
    if (el) {
        var spinner = document.createElement(tag);
        spinner.innerHTML = "<img class='spinner' src='" + fishEyePageContext + "/" + fishEyeSTATICDIR + "/images/spinner.gif' />";
        if (Replace) {
            el.parentNode.replaceChild(spinner,el)
        } else {
            el.parentNode.insertBefore(spinner, el.nextSibling);
        }
        return true;
    }
    return false;
}

function stopSpin(el){
    var emptyDiv = document.createElement("div");
    el.parentNode.replaceChild(emptyDiv,el.nextSibling);
}

