/**
*	@class: quote
*	@description: provides the functionality for building a custom quote (ajax)
*	@function: initialize
*	@function: Update 
*	@function: ValidateType 
*	@function: ValidateQty 
*	@function: ValidateName 
*	@function: ValidateEmail
*	@function: AddError
*	@function: AddError
*	@function: RemoveError
*	@function: ErrorExists
*	@function: UpdateErrorPositions
*	@function: ToggleCalculating
*	@function: HideOptions
*	@function: Send
*	@function: ShowSuccess
*/
var Quote = Class.create({
    initialize: function(form)
    {
        this.form = form

        this.total = $('cost')
        this.printingMethodField = $('printing-method')
		this.printMethod = 'Screen Printing'
        this.quantityLimit = 20
		this.processPrintLimit = 100
		
		// visible names for the printing options
		this.textScreenPrinting = 'Screen Printing'
		this.textDTGBubble = 'DTG (Digital) Printing'
		this.textVinylBubble = 'Transfer (Vinyl) Printing'
		this.textContact = 'Contact Us (POA)'
		
		// links for the different printing methods
		this.linkScreenPrinting = 'http://www.indigoclothing.com/screen-printing/'
		this.linkVinylBubble = 'http://www.indigoclothing.com/transfer-printing/'
		this.linkDTGBubble = 'http://www.indigoclothing.com/direct-to-garment-digital-printing/'

        // HTML template for errors (visibility hidden stops initial flicker)
        this.errorString = '<div class="error" id="#{target}-error" style="visibility: hidden">#{error}</div>'

        // Array of error ids
        this.errors = []

        this.HideOptions()

        new Form.Observer(this.form, 0.8, this.Update.bind(this))
        // Monitor the form for changes
        this.form.observe('submit', this.Send.bindAsEventListener(this))
    },

    Update: function(form)
    {
        // hide the options not required initially, or conditionally
        this.HideOptions()

        // check what type of printing type is specified.
        var selectedType = this.ValidateType(this.form.getInputs('radio', 'data[CustomQuote][type]').find(function(input) {
            return input.checked == true
        }))

        if (selectedType.value == 'printed')
        {
            $('print-type-field').show()
            $('embroidered').hide()
            $('average-colours-field').hide()

            // check what type of printing type is specified.
            var selectedPrintType = this.ValidatePrintType
            (
            this.form.getInputs('radio', 'data[CustomQuote][print_type]').find
            (
            function(input)
            {
                return input.checked == true
            }
            )
            )

            // show the garment fields or not
            if (this.ShowHideSizeField(selectedPrintType, $('average-colours'), $('quantity'), $('base-colours')))
            {
                $('garment-size-field').show()

                if (this.ShowHideDTGSizeField(selectedPrintType, $('average-colours'), $('quantity'), $('base-colours'))) {
                    $('dtg-garment-size-field').show()
                }
                else if (this.ShowHideVinylSizeField(selectedPrintType, $('average-colours'), $('quantity'), $('base-colours'))) {
                    $('vinyl-garment-size-field').show()
                }
            }
            else
            {
                $('garment-size-field').hide()
            }

            // only show the avg colours option if colour type is spot
            if (selectedPrintType.value == 'spot')
            {
                $('average-colours-field').show()

                if ($('average-colours').value == 1) {
                    if ($('quantity').value > 0 && ($('quantity').value < this.quantityLimit)) {
                        $('base-colour-field').show()
                    }
                } else if ($('average-colours').value > 1) {
                    if ($('quantity').value > 0 && ($('quantity').value < this.quantityLimit)) {
                        $('base-colour-field').show()
                    }
                }
                if ($('average-colours').value != "" && $('quantity').value != "" && $('base-colours').value != "")
                {
                    this.ValidateIndigoAvailable(selectedPrintType, $('average-colours'), $('quantity'), $('base-colours'))
                }
            }
            else if (selectedPrintType.value == 'process')
            {
                $('average-colours-field').hide()

                if (!isNaN($('quantity').value) && $('quantity').value != "") {
                    $('base-colour-field').show()
                }
                if ($('quantity').value != "" && $('base-colours').value != "")
                {
                    this.ValidateIndigoAvailable(selectedPrintType, $('average-colours'), $('quantity'), $('base-colours'))
                }
            }

            if (selectedType.value != "")
            {
                this.ValidateQuantity($('quantity'), 'printed')
            }

			// determine if the print method text should be shown and what it should be
			this.ShowHidePrintMethod(selectedType.value, selectedPrintType.value, $('average-colours'), $('quantity'), $('base-colours'))

        }
        else if (selectedType.value == 'embroidered')
        {
            $('embroidered').show()
            $('print-type-field').hide()

            if (selectedType.value != "")
            {
                this.ValidateQuantity($('quantity'), 'embroidered')
            }

            this.RemoveError('base-colour-field')
        }
        else {

            }

        this.UpdateErrorPositions()

        /* 
		 * Update the cost per item. when there's no type or quantity errors, update the form with the
		 * 	with the query response.
		 */
        if (!this.ErrorExists($('type-field-error'))
        && !this.ErrorExists($('quantity-field-error'))
        && !this.ErrorExists($('base-colour-field-error')))
        {
            this.form.request({
                onLoading: function()
                {
                    this.ToggleCalculating()
                }.bind(this),
                onSuccess: function(transport)
                {
                    this.ToggleCalculating()

                    // set the value of the 'cost' field to the return value from the Ajax request
                    this.total.innerHTML = transport.responseText

                }.bind(this),
                onFailure: function()
                {
                    this.ToggleCalculating()
                }.bind(this)
            })
        }
    },

    /*
	 *	@description: just determine whether to display the garment size field.
	 */
    ShowHideSizeField: function(print_type, print_colours, quantity, base_colour)
    {
        if (isNaN(print_colours.value) || print_colours.value == null) {
            return false;
        }
        if (isNaN(quantity.value) || quantity.value == null) {
            return false;
        }

        if (quantity.value > 0)
        {
            switch (print_type.value)
            {
            case 'spot':
                if (print_colours.value == 1 && quantity.value < this.quantityLimit && base_colour.value != "")
                {
                    return true;
                }
                else if (print_colours.value > 1 && quantity.value < this.quantityLimit && base_colour.value == "light")
                {
                    return true;
                }
                break;
            case 'process':
                if (quantity.value < 100 && base_colour.value == "light")
                {
                    return true;
                }
                break;
            }
        }

        return false;

    },

    /*
	 * written to be dependent on the ShowHideSizeField being called first.
	 */
    ShowHideDTGSizeField: function(print_type, print_colours, quantity, base_colour)
    {
        switch (print_type.value)
        {
        case 'spot':
            if (print_colours.value == 1 && quantity.value < this.quantityLimit && base_colour.value == 'light')
            {
                return true;
            }
            else if (print_colours.value > 1 && quantity.value < this.quantityLimit && base_colour.value == 'light')
            {
                return true;
            }
            break;
        case 'process':
            if (quantity.value < 100 && base_colour.value == 'light')
            {
                return true;
            }
            break;
        }

        return false;

    },

    /*
	 * written to be dependent on the ShowHideSizeField being called first.
	 */
    ShowHideVinylSizeField: function(print_type, print_colours, quantity, base_colour)
    {
        switch (print_type.value)
        {
        case 'spot':
            if (print_colours.value == 1 && quantity.value < this.quantityLimit && base_colour.value == 'dark')
            {
                return true;
            }
            break;
        }

        return false;

    },

    /*
		@description: validate the quote type ('Screen Printed' or 'Embroided') onSubmit
	*/
    ValidateType: function(selected)
    {
        if (selected == undefined)
        {
            this.AddError('type-field', 'Please choose a design type')
            return false
        }
        else
        {
            this.RemoveError('type-field')
            return selected
        }
    },

    /*
		@description: validate the quote type ('Screen Printed' or 'Embroided') onSubmit
	*/
    ValidatePrintType: function(selected)
    {
        if (selected == undefined)
        {
            this.AddError('print-type-field', 'Please choose a print type')
            return false
        }
        else
        {
            this.RemoveError('print-type-field')
            return selected
        }
    },

    /*
		@description: determine whether indigo can handle the order
	*/
    DeterminePrintMethod: function(select_type, print_type, print_colours, quantity, base_colour)
    {	
        if (select_type == 'printed') 
		{
            if (print_type == 'spot') 
			{
				if (print_colours.value > 1) 
				{ 
					if (quantity.value > 0 && quantity.value < this.quantityLimit) 
					{
						if (base_colour.value == 'light') 
						{
                			return this.textDTGBubble
            			} 
						else if (base_colour.value == 'dark') 
						{
							return this.textContact
						}
					}
					else if (quantity.value >= this.quantityLimit)  {
						return this.textScreenPrinting
					} 
				} 
				else if (print_colours.value == 1) 
				{
					if (quantity.value > 0 && quantity.value < this.quantityLimit) 
					{
						if (base_colour.value == 'light') 
						{
                			return this.textDTGBubble
            			} 
						else if (base_colour.value == 'dark') 
						{
							return this.textVinylBubble
						}	
					} 
					else if (quantity.value >= this.quantityLimit) {
						return this.textScreenPrinting
					}
				}
			} 
			else if (print_type == 'process') 
			{ 
				if (quantity.value > 0 && quantity.value < this.processPrintLimit) 
				{
					if (base_colour.value == 'light') 
					{
            			return this.textDTGBubble
        			} 
					else if (base_colour.value == 'dark') 
					{
						return this.textContact
					}
				} 
				else if (quantity.value >= this.processPrintLimit) 
				{
					if (base_colour.value == 'dark') 
					{
						return this.textContact
					} 
					else if (base_colour.value == 'light') 
					{
						return this.textScreenPrinting
					}
				}
			}
        }

        return false

    },

    /*
		@description: determine whether indigo can handle the order
	*/
    ShowHidePrintMethod: function(select_type, print_type, print_colours, quantity, base_colour)
    {
        if (select_type == 'printed') {
	
			this.printMethod = this.DeterminePrintMethod(select_type, print_type, print_colours, quantity, base_colour);
			
			printLink = '';

			if (this.printMethod != false) {
				if (this.printMethod != this.textContact) {
					switch (this.printMethod) {
						case this.textDTGBubble:
							printLink = this.linkDTGBubble
						break;
						case this.textVinylBubble:
							printLink = this.linkVinylBubble
						break;
						case this.textScreenPrinting:
							printLink = this.linkScreenPrinting
						break;
					}
	                
					if (printLink == '') {
						this.printingMethodField.innerHTML = this.printMethod
					} else {
						this.printingMethodField.innerHTML = "<a href='" + printLink + "'>" + this.printMethod + "</a>"
					}
					
	                $('printing-method-field').show()
	
				}			
			}
			
        } else {
            $('printing-method-field').hide()
        }
    },

    /*
		@description: determine whether indigo can handle the order
	*/
    ValidateIndigoAvailable: function(print_type, print_colours, quantity, base_colour)
    {
        if (print_type.value == 'spot' && print_colours.value > 1 && quantity.value < this.quantityLimit && base_colour.value == 'dark')
        {
            this.total.innerHTML = "0.00"
            this.AddError('base-colour-field', 'Please contact indigo for this order')
        }
        else if (print_type.value == 'process' && base_colour.value == 'dark')
        {
            this.total.innerHTML = "0.00"
            this.AddError('base-colour-field', 'Please contact indigo for this order')
        }
        else
        {
            this.RemoveError('base-colour-field')
        }
    },

    /*
		@description: validate the order qty
	*/
    ValidateQuantity: function(quantity, selectedType)
    {
        if (isNaN(quantity.value))
        {
            this.AddError('quantity-field', 'Please make sure the quantity is a number')
        }
        else if (quantity.value < 1)
        {
            this.AddError('quantity-field', 'Please make sure you enter a quantity')
        }
		else if (quantity.value < this.quantityLimit && selectedType == 'embroidered' )
		{
			this.AddError('quantity-field', 'Our minimum order quanity is ' + this.quantityLimit + '.<br />If you want to mix several garments please give us a call on <strong>0800 061 2207</strong>')
		}
        else
        {
            this.RemoveError('quantity-field')
        }
    },

    /*
		@description: validate the customer's name field. 
	*/
    ValidateName: function(name)
    {
        if (name.blank())
        {
            this.AddError('name-field', 'Please provide your name')
        }
        else
        {
            this.RemoveError('name-field')
        }
    },

    /*
		@description: validate the customer's email address. 
	*/
    ValidateEmail: function(email)
    {
        if (email.blank())
        {
            this.AddError('email-field', 'Please provide your email address')
        }
        else
        {
            if (!/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,6})$/.test(email))
            {
                this.AddError('email-field', 'Please check that your email address is valid')
            }
            else
            {
                this.RemoveError('email-field')
            }
        }
    },

    AddError: function(target, error)
    {
        var targetError = $(target + '-error')

        if (this.ErrorExists(targetError))
        {
            this.RemoveError(target)
        }

        var error = this.errorString.interpolate({
            target: target,
            error: error
        })
        error = $(target).insert({
            'before': error
        }).previous()

        var width = parseInt(error.getStyle('width').replace('px', ''))

        var newPosition = width + 7

        error.setStyle({
            left: '-' + newPosition + 'px',
            width: width + 'px',
            visibility: 'visible'
            // Stops the flicker as field is edited
        })

        this.errors.push(target + '-error')

        this.UpdateErrorPositions()
    },

    RemoveError: function(target)
    {
        var error = $(target + '-error')

        if (error != null)
        {
            this.errors = this.errors.without(target + '-error')
            error.remove()
        }
    },

    ErrorExists: function(targetError)
    {
        if (targetError != null)
        {
            return this.errors.any(function(error) {
                return error == targetError.id
            })
        }
        else
        {
            return false
        }
    },

    UpdateErrorPositions: function()
    {
        this.errors.each(function(error) {
            var error = $(error)
            var target = error.next('div.field')
            var top = target.positionedOffset()[1]
            error.setStyle({
                top: top + 'px'
            })
        })
    },

    /*
	 *	@description: show/hide the calculation spinner
	 */
    ToggleCalculating: function()
    {
        if ($('cost').hasClassName('calculating'))
        {
            $('cost').removeClassName('calculating')
        }
        else
        {
            $('cost').addClassName('calculating')
        }
    },

    HideOptions: function()
    {
        $('embroidered').hide()
        $('base-colour-field').hide()
        $('print-type-field').hide()
        $('garment-size-field').hide()
        $('dtg-garment-size-field').hide()
        $('vinyl-garment-size-field').hide()
        $('average-colours-field').hide()
        $('printing-method-field').hide()
    },

    /*
	 *	@description: submits the information to the custom quote script and avoids the normal form submit process.
	 *		validates that the right type, quantity, customer name and email address are present.
	 */
    Send: function(event)
    {
        this.ValidateType(this.form.getInputs('radio', 'data[CustomQuote][type]').find(function(input) {
            return input.checked == true
        }))

		// check what type of printing type is specified.
        var selectedType = this.ValidateType(this.form.getInputs('radio', 'data[CustomQuote][type]').find(function(input) {
            return input.checked == true
        }))

        this.ValidateQuantity($('quantity'), selectedType.value)
        this.ValidateName($('name').getValue())
        this.ValidateEmail($('email').getValue())

        if (this.errors.length == 0)
        {
            this.form.request({
                parameters: {
                    "data[CustomQuote][send]": true
                },
                // Tells the controller this is a full submission not a request for the price
                onSuccess: function(transport)
                {
                    this.ShowSuccess(transport.responseText)
                }.bind(this)
            })
        }

        Event.stop(event)
        // Stop the form from submitting normally
    },

    ShowSuccess: function(message)
    {
        this.form.up('div.wrapper').innerHTML = message
    }
})

/**
*	@class: quote
*	@description: provides the functionality for building a custom quote (ajax)
*	@function initialize
*	@function CustomQuote
*/
var Product = Class.create({
    initialize: function()
    {
        this.CustomQuote($('customquote_form'))
    },

    CustomQuote: function(form)
    {
        new Quote(form)
    }
})
