/*
 *
 * SELECTED METHODS:
 * When an element is selected.
 *
 *
 */

function productSelected($jobDiv)
{
    var productRef = $('#product_reference_' + $jobDiv.attr('index')).val();
    updateProduct(productRef, $jobDiv);
}

function formatSelected($jobLine)
{
    updateBoxCount($jobLine);
    updateJobPrice($jobLine);
}

function optionSelected(event)
{
    var $jobLine = event.data.$jobLine;
    var $jobDiv = event.data.$jobDiv;
    var productRef = $('#product_reference_' + $jobDiv.attr('index')).val();
    updateJobPrice($jobLine);
    updateDeadline(productRef, function()
    {
        testShippers(function()
        {
            updateShippingMethod();
        });
    });
}


/*
 *
 * UPDATE METHODS:
 * Update an element
 *
 */

function updateProduct(productRef, $jobDiv)
{
    if (productMap[productRef] != undefined)
    {
        updateDeadline(productRef, function()
        {
            updateJobDiv($jobDiv, productRef);
            testShippers(function()
            {
                updateShippingMethod();
            });
        });
    }
    else
    {
        $.getJSON(baseUrl + "/pub/ajax/product/" + productRef, function(product)
        {
            productMap[productRef] = product;
            updateDeadline(productRef, function()
            {
                updateJobDiv($jobDiv, productRef);
                testShippers(function()
                {
                    updateShippingMethod();
                });
            });
        });
    }
}

function updateDeadline(productRef, callbackFunction)
{
    if (productRef != 'null' && $('#shipping_country').val() != undefined)
    {
        var job = {};
        job["job.product.reference"] = productRef;
        job["job.order.deliveryAddress.address.country.iso"] = $('#shipping_country').val();
        $.getJSON(baseUrl + "/pub/ajax/deadline", job, function(response)
        {
            productMap[productRef].deadLine = response.deadLine;
            if (callbackFunction != undefined) callbackFunction.call();
        });
    }
    else
    {
        if (callbackFunction != undefined) callbackFunction.call();
    }
}


function updateJobDiv($jobDiv, productRef)
{
    unbindJobEvents($jobDiv);

    var $jobLine = $('tr.job_line', $jobDiv);
    var formatRef = $('select.format_reference', $jobLine).val();
    var $jobLineClone = $jobLine.clone();
    var index = $jobDiv.attr('index');

    $('td.product', $jobLineClone).remove();

    updateFormat($('select.format_reference', $jobLineClone), productRef);
    updateOptions($('div.job_options', $jobLineClone), productMap[productRef].options, index);
    updateDescription($('tr.description_line', $jobDiv), productMap[productRef].description);
    updateDeadlineShow($('tr.deadline_line', $jobDiv), productMap[productRef].deadLine);

    $('td:not(.product)', $jobLine).remove();
    $jobLine.append($('td', $jobLineClone));

    selectDefaultValues($jobLine, productRef, formatRef);

    if ($('div.job_concerns').find('select.product_reference[value=null]').length < 2) appendJobLine();
    updateBoxCount($jobLine);
    bindJobEvents($jobDiv);
}

function updateFormat($productFormatSelect, productRef)
{
    var formats = productMap[productRef].formats

    var $clone = $productFormatSelect.clone();
    $('option[value!=null]', $clone).remove();
    for (i in formats)
    {
        var format = formats[i];
        var $formatToAppend = $('<option></option>').val(format.reference).html(format.label + " (" + format.width + "x" + format.height + " mm)");
        $clone.append($formatToAppend);
    }
    if ($('option[value!=null]', $clone).length == 1)
    {
        $('option[value!=null]', $clone).attr('selected', 'selected');
    }
    $productFormatSelect.replaceWith($clone);
}

function updateOptions($productOptionsDiv, options, index)
{
    var $clone = $productOptionsDiv.clone();
    $('span.option_reference:not(.default)', $clone).remove();
    var $defaultOption = $('span.option_reference.default', $clone);
    if (options == undefined || options.length == 0)
    {
        $defaultOption.show();
    }
    else
    {
        for (var i in options)
        {
            var option = options[i];
            var $optionToAppend = $defaultOption.clone();
            $optionToAppend.removeClass('default');
            $('input', $optionToAppend).removeAttr('selected_values').attr('value', option.reference).attr('name', 'order.customerJobs[' + index + '].productOptions[' + i + ']');
            $('span.option_label', $optionToAppend).text(option.label);
            $clone.append($optionToAppend);
            $optionToAppend.show();
        }
        $defaultOption.hide();
    }
    $productOptionsDiv.replaceWith($clone);
}

function updateDescription($descriptionLine, description)
{
    if (description != undefined)
    {
        $('td', $descriptionLine).text(description);
        $descriptionLine.show();
    }
    else
    {
        $descriptionLine.hide();
    }
}

function updateDeadlineShow($deadlineLine, deadLine)
{
    if (deadLine != undefined)
    {
        $('td', $deadlineLine).html("Deadline&nbsp;: " + deadLine);
        $deadlineLine.show();
    }
    else
    {
        $deadlineLine.hide();
    }
}

/**
 * Select the default values for this job
 * @param $jobLine
 * @param productRef
 * @param formatRef
 */
function selectDefaultValues($jobLine, productRef, formatRef)
{
    selectDefaultFormat($jobLine, productRef, formatRef);
    selectDefaultOptions($jobLine, productRef, formatRef);
    selectDefaultQuantity($jobLine, productRef, formatRef);
    updateJobPrice($jobLine);
}

function selectDefaultFormat($jobLine, productRef, formatRef)
{
    var $selectFormat = $('select.format_reference', $jobLine);
    if (productRef == 'null')
    {
        $selectFormat.val('null');
    }
    else
    {
        var $defaultFormat = $('option[value=null]', $selectFormat);
        var selectedValue = $defaultFormat.attr('selected_value');
        if (selectedValue != "")
        {
            $selectFormat.val(selectedValue);
            $defaultFormat.attr('selected_value', '');
        }
    }
}

function selectDefaultOptions($jobLine, productRef, formatRef)
{
    if (productRef != 'null')
    {
        var $optionsDiv = $('div.job_options', $jobLine);
        var $defaultOption = $('input[value=null]', $optionsDiv);
        var selectedValueList = $defaultOption.attr('selected_values').split(" ");
        if (selectedValueList.length > 0)
        {
            $defaultOption.attr('selected_values', '');
            $('input[value!=null]', $optionsDiv).each(function()
            {
                if ($.inArray($(this).val(), selectedValueList) != -1)
                {
                    $(this).attr('checked', 'checked');
                }
                else
                {
                    $(this).removeAttr('checked');
                }
            });
        }
    }
}

function selectDefaultQuantity($jobLine, productRef, formatRef)
{
    var qty = 0;
    var $inputQuantity = $('input.quantity', $jobLine);
    if (productRef != 'null')
    {
        var qtyText = $inputQuantity.attr('selected_value');

        if (qtyText != '')
        {
            qty = parseInt(qtyText);
            $inputQuantity.attr('selected_value', '');
        }
        else
        {
            var product = productMap[productRef];
            qty = product.defaultBaseQuantity;
        }
    }

    $inputQuantity.val(qty);
    $('input.quantity_hidden', $jobLine).val(qty);
}

/*
 *
 * BINDING in the job level
 *
 */

function unbindJobEvents($jobDiv)
{
    var $jobLine = $('tr.job_line', $jobDiv);
    $('select.product_reference', $jobLine).unbind(change);
    $('select.format_reference', $jobLine).unbind(change);
    $('span.option_reference', $jobLine).unbind('click keyup');
    $('a.quantity_decrease', $jobLine).unbind('click');
    $('a.quantity_increase', $jobLine).unbind('click');
}

function bindJobEvents($jobDiv)
{
    var $jobLine = $('tr.job_line', $jobDiv);
    $('select.product_reference', $jobLine).bind(change, function()
    {
        productSelected($jobDiv);
    });
    $('select.format_reference', $jobLine).bind(change, function()
    {
        testShippers(function()
        {
            formatSelected($jobLine);
            updateShippingMethod();
        });
    });
    $('span.option_reference', $jobLine).bind('click keyup', {$jobLine:$jobLine, $jobDiv:$jobDiv}, optionSelected);
    $('a.quantity_decrease', $jobLine).bind('click', {$jobLine:$jobLine, increase:-1}, increaseQty);
    $('a.quantity_increase', $jobLine).bind('click', {$jobLine:$jobLine, increase:1}, increaseQty);
}

/**
 * append a new jobLine to the order
 */
function appendJobLine()
{
    var $appendable = $('div.job_concerns:last');
    var $clone = $appendable.clone();
    $('input.quantity', $clone).attr('selected_value', '');
    var newIndex = $('div.job_concerns').length;

    // adapt all index values in css class names and property names
    updateJobIndex($clone, newIndex);

    var $jobDiv = $clone.insertAfter($appendable);
    // update this new job line to clear values and reset select boxes
    $('select.product_reference', $jobDiv).val('null');
    updateJobDiv($jobDiv, 'null');

    // bind behaviours on this new job line
    bindJobEvents($jobDiv);
}

/**
 * update the index of a job
 * @param $jobDiv
 * @param newIndex
 */
function updateJobIndex($jobDiv, newIndex)
{
    var oldIndex = $jobDiv.attr('index');
    $jobDiv.attr('index', newIndex).attr('id', 'job_concerns_' + newIndex);

    // update the class of the div (for a beautiful gray/gold alternance)
    var isEven = $jobDiv.hasClass('even');
    if (isEven) $jobDiv.removeClass('even').addClass('odd');
    else $jobDiv.removeClass('odd').addClass('even');

    // quantity and prices
    $('input.quantity_hidden', $jobDiv).attr('id', 'quantity_hidden_' + newIndex).attr('name', 'order.customerJobs[' + newIndex + '].quantity');
    $('input.quantity', $jobDiv).attr('id', 'quantity_' + newIndex);
    $('input.price', $jobDiv).attr('name', 'order.customerJobs[' + newIndex + '].price');
    $('input.box_count', $jobDiv).attr('name', 'order.customerJobs[' + newIndex + '].boxCount');

    // jobline
    var $jobLine = $('tr.job_line', $jobDiv);
    $jobLine.attr('id', 'job_line_' + newIndex);

    // product
    var $selectProductReference = $('select.product_reference', $jobLine);
    $selectProductReference.attr('id', 'product_reference_' + newIndex).attr('name', 'order.customerJobs[' + newIndex + '].product.reference');
    $('option[value=null]', $selectProductReference).attr('selected_value', '');

    //format
    var $selectFormatReference = $('select.format_reference', $jobLine);
    $selectFormatReference.attr('id', 'format_reference_' + newIndex).attr('name', 'order.customerJobs[' + newIndex + '].format.format.reference');
    $('option[value=null]', $selectFormatReference).attr('selected_value', '');

    //options
    var $optionsDiv = $('div.job_options', $jobLine);
    $optionsDiv.attr('id', 'job_options_' + newIndex);
    $('span.option_reference.default input', $optionsDiv).attr('selected_values', '');
    $('span.option_reference:not(.default) input', $optionsDiv).each(function()
    {
        var $input = $(this);
        var name = $input.attr('name');
        var newName = name.replace('order.customerJobs[' + oldIndex + ']', 'order.customerJobs[' + newIndex + ']');
        $input.attr('name', newName);
    });
}