/**
* jQuery is not included by default on NOMETA pages, so define a simple version of the $ function for use
* with the video upload form and activate jQuery noConflict mode to prevent any incompatibilities
*/
if ( typeof jQuery == 'function' )
{
    jQuery.noConflict();
}

$ = function(id) {
        return document.getElementById(id);
    };


/**
* Stops the upload and prepares the form for a retry
*
* @param string $errorType Reason why the upload is being aborted
*/
function abortUpload(errorType)
{
    if ( !window.stop )
    {
        document.location.href += ( document.location.href.indexOf('?') != -1 ? '&' : '?' ) + 'error=' + errorType;
    }
    else
    {
        window.stop();

        $('_startUpload').style.cursor = 'pointer';
        $('_startUpload').onclick = prepareUpload;
        $('video_upload_progress').style.visibility = 'hidden';

        displayMessage(errorType);
    }
}

/**
* Begins the upload process
*/
function beginUpload()
{
    _uploadStartTime = ( new Date() ).getTime();
    $('video_upload_progress').style.visibility = 'visible';

    var xmlHttp = createXMLHttpRequest();

    xmlHttp.open('POST', '/content/vidaveeUpload.jhtml?request=LOGIN', true);

    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
        {
            var responseXML = ( navigator.userAgent.indexOf('Firefox') != -1 )
                            ? ( new DOMParser() ).parseFromString(xmlHttp.responseText, 'text/xml')
                            : xmlHttp.responseXML;

            $('sessionToken').value = responseXML.getElementsByTagName('sessionToken')[0].firstChild.nodeValue;
            $('api_ts').value = responseXML.getElementsByTagName('api_ts')[0].firstChild.nodeValue;
            $('api_sig').value = responseXML.getElementsByTagName('api_sig')[0].firstChild.nodeValue;

            var AF_uploadId = ( new Date() ).getTime() + '_' + Math.floor( Math.random() * 1000 );

            $('AF_uploadId').value = AF_uploadId;

            $('url').value = 'http://tribeca.vidavee.com/univision/rest/assets/NewAssetVideo;jsessionid='
                           + $('sessionToken').value + '?AF_uploadId=' + AF_uploadId
                           + '&api_key=' + responseXML.getElementsByTagName('api_key')[0].firstChild.nodeValue
                           + '&api_ts=' + $('api_ts').value
                           + '&api_token=' + $('sessionToken').value
                           + '&api_sig=' + $('api_sig').value;

            document.vv_UPLOAD.action = $('url').value;

            setTimeout( "checkUploadProgress('" + AF_uploadId + "');", 1000 );

            document.vv_UPLOAD.submit();

            $('_startUpload').style.cursor = 'wait';
            $('_startUpload').onclick = function() {
                                            displayMessage('UPLOAD_IN_PROGRESS');
                                        };

            document.vv_UPLOAD.action = '';
        }
    };
    xmlHttp.send(null);
}

/**
* Determines how much time is remaining for the upload and returns it in mm:ss format
*
* @param string $percentageUploaded the percentage of the upload that has been completed thus far
*
* @return string mm:ss formatted time remaining
*/
function calculateTimeRemaining(percentageUploaded)
{
    var elapsed_sec = Math.floor( ( ( new Date() ).getTime() - _uploadStartTime ) / 1000 );
    var rate = elapsed_sec / percentageUploaded;
    var remaining = rate * (100 - percentageUploaded);

    var min = Math.floor(remaining / 60);
    var sec = Math.ceil(remaining % 60);
        sec = (sec < 10) ? '0' + sec : sec;

    return ( min + ':' + sec );
}

/**
* Checks URL to determine if any errors are indicated and display an alert if so.
*/
function checkErrorParam()
{
    var errorType = params()['error'];

    if ( errorType != null )
    {
        displayMessage(errorType);
    }
}

/**
* Checks how the upload has progressed and directs program flow accordingly
*
* @param string $AF_uploadId the unique upload identifier for the video
*/
function checkUploadProgress(AF_uploadId)
{
    var xmlHttp = createXMLHttpRequest();

    xmlHttp.open(
                'POST',
                '/content/vidaveeUpload.jhtml?request=UPLOAD_PROGRESS&sessionToken=' +
                $('sessionToken').value + '&AF_uploadId=' + AF_uploadId,
                true
            );

    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
        {
            var responseXML = (navigator.userAgent.indexOf('Firefox') != -1)
                            ? (new DOMParser()).parseFromString(xmlHttp.responseText, 'text/xml')
                            : xmlHttp.responseXML;

            if (responseXML.getElementsByTagName('sizeTotal').length != 0)
            {
                if ( responseXML.getElementsByTagName('sizeTotal')[0].firstChild.nodeValue > (MAX_FILE_SIZE * 1000000) )
                {
                    abortUpload( 'FILE_SIZE' );
                }
                else if ( uploadStoppedOnClientSide(responseXML) )
                {
                    abortUpload( 'OTHER' );
                }
                else
                {
                    var dockeyChildNode = responseXML.getElementsByTagName('dockey')[0].firstChild;
                    dockey = (dockeyChildNode != null) ? dockeyChildNode.nodeValue : 'N/A';

                    updateProgress(
                                    responseXML.getElementsByTagName('uploadId')[0].firstChild.nodeValue,
                                    responseXML.getElementsByTagName('complete')[0].firstChild.nodeValue,
                                    responseXML.getElementsByTagName('percentageUploaded')[0].firstChild.nodeValue,
                                    dockey
                                  );
                }
            }
            else
            {
                if ( Math.floor( ( (new Date()).getTime() - _uploadStartTime ) / 1000 ) < 60 )
                {
                    setTimeout( "checkUploadProgress('" + AF_uploadId + "');", 5000 );
                }
                else
                {
                    abortUpload( 'INIT_FAIL' );
                }
            }
        }
    };
    xmlHttp.send(null);
}

/**
* Creates XMLHttpRequest object used for ajax requests
*
* @return XMLHttpRequest
*/
function createXMLHttpRequest()
{
    var result = null;

    try
    {
        result = new XMLHttpRequest();
    }
    catch(e)
    {
        try
        {
            result = new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(e2)
        {
            alert('Usted debe activar Active Scripting y controles ActiveX para usar esta forma.');
        }
    }

    return result;
}

/**
* Displays a message to the user
*
* @param string $msgType the type of message to be displayed
*/
function displayMessage(msgType)
{
    switch (msgType)
    {
        case 'CONFIRM_TERMS':
            alert('Debes confirmar que ha leído las reglas y que usted tienes derechos al contenido del archivo.');
            break;
        case 'FILE_SIZE':
            alert('El archivo que ha intentado subir es demasiado grande. Por favor, limite su tamaño a ' + MAX_FILE_SIZE + ' MB.');
            break;
        case 'FORM_INCOMPLETE':
            alert('Por favor, rellene toda la información requerida.');
            break;
        case 'INIT_FAIL':
            alert('La carga de su archivo no pudo comenzar.  Por favor intenta de nuevo.');
            break;
        case 'INVALID_FORMAT':
            alert('Este formato de archivo no es aceptable. El formato del archivo debe ser uno de los siguientes: WMV, MPG, AVI, FLV, MOV.');
            break;
        case 'UPLOAD_IN_PROGRESS':
            alert('Su carga ya está en marcha. Este botón está desactivado.');
            break;
        case 'OTHER':
        default:
            alert('Lo sentimos, pero occurrio un error.  Por favor intenta de nuevo.');
            break;
    }
}

/**
* Handler for the customized file selection input area
*
* @param string $file the input file name that was selected
*/
function handleFileSelection(file)
{
    $('fake_Asset').value = file;

    if ( $('fake_Asset').onchange )
    {
        $('fake_Asset').onchange();
    }
}

/**
* Validation function
*
* @param HTMLElement $ele the element that needs to be validated
*
* @return bool true if the field has been filled out, false if not
*/
function isFilledOut(ele)
{
    switch (ele.type)
    {
        case 'text':
        case 'file':
        case 'textarea':
            if ( ele.value == '' )
                return false;

            if (ele.id != 'fake_Asset')
                return true;

            var ext = ele.value.match('\.([^\.]+)$')[1].toUpperCase();

            if (ext == 'WMV' || ext == 'MPG' || ext == 'AVI' || ext == 'FLV' || ext == 'MOV')
            {
                return true;
            }
            else
            {
                displayMessage('INVALID_FORMAT');
                return false;
            }
            break;
        case 'select':
        case 'select-one':
        case 'select-multiple':
            var sel = 0;

            for (var j = 0; j < ele.length; j++)
            {
                if (ele.options[j].selected) sel++;
            }

            return (sel > 0);
            break;
        default:
            return false;
            break;
    }
}

/**
* Returns array of url params
*
* @return array key/value pairs of url params
*/
function params()
{
    var qsParm = new Array();

    var query = window.location.search.substring(1);
    var parms = query.split('&');
    for (var i=0; i<parms.length; i++)
    {
        var pos = parms[i].indexOf('=');
        if (pos > 0)
        {
            var key = parms[i].substring(0,pos);
            var val = parms[i].substring(pos+1);

            qsParm[key] = val;
        }
    }

    return qsParm;
}

/**
* Performs pre-upload preparation and then begins uploading the video
*/
function prepareUpload()
{
    if ( !validateInput() )
    {
        displayMessage( 'FORM_INCOMPLETE' );
    }
    else if (!$('rules_rights').checked)
    {
        displayMessage( 'CONFIRM_TERMS' );
    }
    else
    {
        beginUpload();
    }
}

function setNotFilledOut(ele)
{
    if ( ele.style.border != '1px dashed red' && ele.style.border != 'red 1px dashed' )
    {
        ele.style.border = '1px dashed red';
        ele.onchange = Function('this.style.border = default_field_border; this.onchange = ' + ( (this.onchange != 'undefined') ? "Function('" + this.onchange + "')" : 'null' ) + ';');
    }
}

/**
* Update the hidden assetSets field that contains a comma-delimited list of sets to which
* the video should be associated.
*
* @param HTMLSelectElement $setBox the multiple select box that contains the list of sets the user can choose
*/
function updateAssetSets(setBox)
{
    $('assetSets').value = '';

    for (var i = 0; i < setBox.length; i++)
    {
        if ( setBox.options[i].selected )
        {
            $('assetSets').value += ( $('assetSets').value != '' )
                                  ? ',' + setBox.options[i].value
                                  : setBox.options[i].value;
        }
    }
}

/**
* Updates the progress bar
*
* @param string $AF_uploadId the unique upload identifier
* @param string $complete 'true' if the upload is complete, 'false' if not
* @param string $percentageUploaded percentage of the upload that has been completed thus far
* @param string $dockey the asset dockey, which will be available when the upload is complete
*/
function updateProgress(AF_uploadId, complete, percentageUploaded, dockey)
{
    if ( complete == 'true' && dockey != '$dockey' )
    {
        percentageUploaded = '100';
        var timeRemaining = -1;
    }
    else if ( percentageUploaded != 0 )
    {
        var timeRemaining = calculateTimeRemaining(percentageUploaded);
    }
    else
    {
        var timeRemaining = 0;
    }

    updateProgressMeter(percentageUploaded, timeRemaining);

    var doneButInvalidDockey = ( complete == 'true' && dockey == '$dockey' && dockeyRetry < 10 );

    if ( doneButInvalidDockey )
    {
        dockeyRetry++;
    }

    if ( complete == 'false' || doneButInvalidDockey )
    {
        setTimeout( "checkUploadProgress('" + AF_uploadId + "');", 1000 );
    }
    else
    {
        if (dockey == '$dockey')
        {
            dockey = 'N/A';
        }

        uploadComplete(dockey);
    }
}

/**
* Updates the progress meter for the upload, which consists of the progress bar, percentage uploaded, and
* estimated time remaining
*
* @param string $percentageUploaded percentage of the upload that has been completed thus far
* @param string $timeRemaining mm:ss formatted time remaining
*/
function updateProgressMeter(percentageUploaded, timeRemaining)
{
    $('progress_bar_updater').style.width = Math.floor( 263 * ( 1 - ( percentageUploaded / 100 ) ) ) + 'px';
    $('progress_bar_updater').style.left = Math.ceil( 263 * ( percentageUploaded / 100 ) ) + 2 + 'px';

    $('progress_percentage').innerHTML = percentageUploaded + '%';

    if (timeRemaining != 0 && timeRemaining != -1)
    {
        $('progress_estimate').innerHTML = '(about ' + timeRemaining + ' remaining)';
    }
    else if (timeRemaining == -1)
    {
        $('progress_estimate').style.display = 'none';
    }
}

/**
* Checks to see if the upload was cancelled on the client side
*
* @param XMLObject $responseXML the xml response from the uploadProgress ajax request
*
* @return bool true if it is determined that the upload was stopped on the client side, false if not
*/
function uploadStoppedOnClientSide(responseXML)
{
    return (
        responseXML.getElementsByTagName('complete')[0].firstChild.nodeValue == 'false' && (
            responseXML.getElementsByTagName('dockey')[0].firstChild == null ||
            responseXML.getElementsByTagName('dockey')[0].firstChild.nodeValue != '$dockey'
        ) && responseXML.getElementsByTagName('uploadProgressUrl')[0].firstChild == null
    );
}

/**
* Validates form input and returns whether or not the upload can proceed
*
* @return bool true if the upload can proceed, false if not
*/
function validateInput()
{
    var inputFields = $('vv_UPLOAD').elements;

    for (var i = 0; i < inputFields.length; i++)
    {
        if ( !inputFields[i].disabled && inputFields[i].getAttribute('required') == 'required' )
        {
            switch (inputFields[i].id)
            {
                case 'Asset':
                    var ele = $('fake_Asset');
                    break;
                default:
                    var ele = inputFields[i];
                    break;
            }

            if ( !isFilledOut(ele) )
            {
                setNotFilledOut(ele);
                return false;
            }
            else if ( ele.onchange )
            {
                ele.onchange();
            }
        }
    }

    return true;
}

/**
* Dockey is not always available the instant the upload is complete, so use this variable to keep track of
* how many times we've retried.  If we've retried too many times, the process will give up and proceed to
* uploadComplete with 'N/A' as the dockey
*/
var dockeyRetry = 0;
