var MixTek = Class.create();
MixTek.prototype = {
    initialize: function(form, fields) {
        this.form = form
        this.fields = fields

        // Give the fields a class so we can do add some different CSS
        $A(document.getElementsByClassName('field')).each(function(field) {
            field.addClassName('enhanced')
        })
        this.form.addClassName('enhanced')

        this.contacts = {
            gender: [
                {id: '4', detail: 'Female (Socket)'},
                {id: '5', detail: 'Male (Plug)'}
            ],
            signalStyle: [
                {id:'00', detail: 'No Signal Contacts'},
                {id:'T1', detail: 'Vertical PC Tail, 3mm tail'},
                {id:'T2', detail: 'Vertical PC Tail, 4mm tail'},
                {id:'L1', detail: 'Horizontal PC Tail, 3mm tail'},
                {id:'L2', detail: 'Horizontal PC Tail, 4.5mm tail'},
                {id:'C1', detail: 'Crimp 24-28 AWG (Small Bore)'},
                {id:'D1', detail: 'Crimp 22 AWG (Large Bore)'},
                {id:'S1', detail: 'Vertical Surface Mount'},
                {id:'S2', detail: 'Horizontal Surface Mount'}
            ],
            signalFinish: [
                {id: '00', detail: 'No Signal Contacts'},
                {id: '01', detail: 'Gold + Tin/Lead (Female PC Tail Only)'},
                {id: '05', detail: 'Gold'},
                {id: '22', detail: 'Gold + Tin/Lead (Male PC Tail only)'},
                {id: '42', detail: 'Gold + Tin (All PC Tail & Female Crimp)'}
            ],
            jackscrew: [
                {id: '00', detail:'None Assembled'},
                {id: 'F1', detail:'Hexagonal slotted jackscrew'},
                {id: 'F2', detail:'Hex socket jackscrew'},
                {id: 'F3', detail:'Guide Pin with Panel Mount'},
				{id: 'F8', detail:'Reverse fix with slotted nut, 3.5mm stud length'},
				{id: 'F9', detail:'Reverse fix with slotted nut, 5mm stud length'},
				{id: 'FB', detail:'Hex socket jackscrew with guide pin'},
				{id: 'FC', detail:'101Lok jackscrew'},
                {id: 'M1', detail:'Jackscrew Nut only'},
                {id: 'M2', detail:'Jackscrew Nut with Vertical 3.5mm Board Mount Stud'},
                {id: 'M3', detail:'Jackscrew Nut with Vertical 5mm Board Mount Stud'},
                {id: 'M5', detail:'Jackscrew Nut with Horizontal 5mm Board Mount Slotted Bolt'},
                {id: 'M7', detail:'Jackscrew Nut with Horizontal 5mm Board Mount Hex Skt Bolt'},
				{id: 'MA', detail:'Reverse Fix jackscrew with slotted head'},
				{id: 'MB', detail:'Reverse Fix jackscrew with hex socket head'},
				{id: 'MC', detail:'101Lok jackscrew retainer'},
				{id: 'MD', detail:'101Lok jackscrew retainer with 5mm Board Mount Stud'}
            ],
            special: [
                {id: '000', detail:'No Special contacts fitted or supplied'},
                {id: '301', detail:'Coax - Female Vertical PC Tail, 3mm tail'},
                {id: '302', detail:'Coax - Female Vertical PC Tail, 4.5mm tail'},
                {id: '305', detail:'Coax - Female Crimp Straight, &Oslash;2.00mm cable (RG178)'},
                {id: '306', detail:'Coax - Female Crimp Straight, &Oslash;2.40mm cable (PTFE Cellular)'},
                {id: '307', detail:'Coax - Female Crimp Straight, &Oslash;2.70mm cable (RG174, RG179, RG316)'},
                {id: '308', detail:'Coax - Female Crimp 90&deg;, &Oslash;2.00mm cable (RG178)'},
                {id: '309', detail:'Coax - Female Crimp 90&deg;, &Oslash;2.70mm cable (RG174, RG179, RG316)'},
                {id: '311', detail:'Coax - Male Vertical PC Tail, 3mm tail'},
                {id: '312', detail:'Coax - Male Vertical PC Tail, 4.5mm tail'},
                {id: '313', detail:'Coax - Male Horizontal PC Tail, 3mm tail'},
                {id: '314', detail:'Coax - Male Horizontal PC Tail, 4.5mm tail'},
                {id: '315', detail:'Coax - Male Crimp Straight, &Oslash;2.00mm cable (RG178)'},
                {id: '316', detail:'Coax - Male Crimp Straight, &Oslash;2.40mm cable (PTFE Cellular)'},
                {id: '317', detail:'Coax - Male Crimp Straight, &Oslash;2.70mm cable (RG174, RG179, RG316)'},
                {id: '318', detail:'Coax - Male Crimp 90&deg;, &Oslash;2.00mm cable (RG178)'},
                {id: '319', detail:'Coax - Male Crimp 90&deg;, &Oslash;2.70mm cable (RG174, RG179, RG316)'},
                {id: '321', detail:'Power - Female Vertical PC Tail, 3.5mm tail'},
                {id: '322', detail:'Power - Female Vertical PC Tail, 5mm tail'},
                {id: '325', detail:'Power - Female Crimp Straight, 12 AWG cable'},
                {id: '326', detail:'Power - Female Crimp Straight, 14 AWG cable'},
                {id: '327', detail:'Power - Female Crimp Straight, 16 AWG cable'},
                {id: '331', detail:'Power - Male Vertical PC Tail, 3.5mm tail'},
                {id: '332', detail:'Power - Male Vertical PC Tail, 5mm tail'},
                {id: '333', detail:'Power - Male Horizontal PC Tail, 3.5mm tail'},
                {id: '334', detail:'Power - Male Horizontal PC Tail, 5mm tail'},
                {id: '335', detail:'Power - Male Crimp Straight, 12 AWG cable'},
                {id: '336', detail:'Power - Male Crimp Straight, 14 AWG cable'},
                {id: '337', detail:'Power - Male Crimp Straight, 16 AWG cable'}
            ]
        }

        this.restrictions = {
            female: [
                {id: '00', quantity: '00', finish: ['00'], jackscrew: ['00', 'F1', 'F2', 'F3', 'F8', 'F9', 'FB', 'FC'], special: ['000', '301', '302', '305', '306', '307', '308', '309', '321', '322', '325', '326', '327']},
                {id: 'T1', finish: ['01', '05', '42'], jackscrew: ['00', 'F1', 'F2', 'F3', 'F8', 'F9', 'FB', 'FC'], special: ['000', '301', '302', '321', '322']},
                {id: 'T2', finish: ['01', '05', '42'], jackscrew: ['00', 'F1', 'F2', 'F3', 'F8', 'F9', 'FB', 'FC'], special: ['000', '301', '302', '321', '322']},
                {id: 'C1', finish: ['05', '42'], jackscrew: ['00', 'F1', 'F2', 'F3', 'F8', 'F9', 'FB', 'FC'], special: ['000', '305', '306', '307', '308', '309', '325', '326', '327']},
                {id: 'D1', finish: ['05', '42'], jackscrew: ['00', 'F1', 'F2', 'F3', 'F8', 'F9', 'FB', 'FC'], special: ['000', '305', '306', '307', '308', '309', '325', '326', '327']},
                {id: 'S1', finish: ['01', '05', '42'], jackscrew: ['00', 'F1', 'F2', 'F3', 'F8', 'F9', 'FB', 'FC'], special: ['000', '301', '302', '321', '322']}
            ],
            male: [
                {id: '00', quantity: '00', finish: ['00'], jackscrew: ['00', 'M1', 'M2', 'M3', 'M5', 'M7', 'MA', 'MB', 'MC', 'MD'], special: ['000', '311', '312', '313', '314', '315', '316', '317', '318', '319', '331', '332', '333', '334', '335', '336', '337']},                         
                {id: 'T1', finish: ['05', '22', '42'], jackscrew: ['00', 'M1', 'M2', 'M3', 'MA', 'MB', 'MC'], special: ['000', '311', '312', '331', '332']},
                {id: 'T2', finish: ['05', '22', '42'], jackscrew: ['00', 'M1', 'M2', 'M3', 'MA', 'MB', 'MC'], special: ['000', '311', '312', '331', '332']},
                {id: 'L1', finish: ['05', '22', '42'], jackscrew: ['00', 'M1', 'M5', 'M7', 'MA', 'MB', 'MC', 'MD'], special: ['000', '313', '314', '333', '334']},
                {id: 'L2', finish: ['05', '22', '42'], jackscrew: ['00', 'M1', 'M5', 'M7', 'MA', 'MB', 'MC', 'MD'], special: ['000', '313', '314', '333', '334']},
                {id: 'C1', finish: ['05'], jackscrew: ['00', 'M1', 'M2', 'M3', 'M5', 'M7', 'MA', 'MB', 'MC', 'MD'], special: ['000', '315', '316', '317', '318', '319', '335', '336', '337']},
                {id: 'D1', finish: ['05'], jackscrew: ['00', 'M1', 'M2', 'M3', 'M5', 'M7', 'MA', 'MB', 'MC', 'MD'], special: ['000', '315', '316', '317', '318', '319', '335', '336', '337']},
                {id: 'S1', finish: ['05', '22', '42'], jackscrew: ['00', 'M1', 'M2', 'M3', 'MA', 'MB', 'MC'], special: ['000', '311', '312', '331', '332']},
                {id: 'S2', finish: ['05', '22', '42'], jackscrew: ['00', 'M1', 'M5', 'M7', 'MA', 'MB', 'MC', 'MD'], special: ['000', '313', '314', '333', '334']}
            ]
        }

        this.maxContacts = 50

        this.helpers = $A(document.getElementsByClassName('value-table')).collect(function(helper) {
            helper.addClassName('helper')
            helper.hide()
            return helper
        })
        this.currentHelper = this.helpers[0].show()
        this.currentField = $('gender')

        this.validationWait = 1.5
        this.errors = []
        this.empties = []

        this.totalPartNumbers = 0
        this.disabledJackscrewWarning = false

        //this.form.focusFirstElement()

        // Monitor the fields
        this.fields.each(this.monitor.bind(this))

        // Monitor the document for clicks
        Event.observe(document, 'click', this.hideHelper.bindAsEventListener(this))

        this.form.observe('submit', this.generate.bindAsEventListener(this))

        $('part-numbers').observe('click', function(event) {
            
	    removeLink = Event.findElement(event, 'a')
            Element.extend(removeLink);

            if (removeLink.tagName == 'A' && removeLink.hasClassName('remove'))
            {
                this.removePartNumber(removeLink.up('li'))
            }

            if (!removeLink.hasClassName('extralink'))
            {
                Event.stop(event);
            }
	    
	    if (removeLink.tagName == 'A' && removeLink.hasClassName('regenerate'))
        {    
	    	var index = removeLink.id.substring(removeLink.id.length-1);
	    	var part = $('part_number' + index).value;
	    	this.getPreviewImage(part);
	    }

        }.bind(this))
    },

    monitor: function(field)
    {
        // Check all the fields now in-case the user refreshed
        this.validateField(field.input, field.input.value)

        // Run validation on the field when it's edited
        new Form.Element.Observer(field.input, this.validationWait, this.validateField.bind(this))

        var helper = this.getHelper(field.input)

        // Show the helper when the field is focused
        field.input.observe('focus', this.showHelper.bindAsEventListener(this, helper))
        // Pad the value with leading zero if required
        field.input.observe('blur', this.padField.bindAsEventListener(this))

        this.highlighter(helper.down('table'))

        helper.down('table').observe('click', this.addValue.bindAsEventListener(this, field.input))

    },

    formatPartNumber: function()
    {
        return 'M80 - <span>' +
        this.fields[0].input.value + '</span> <span>' +
        this.fields[1].input.value + '</span> <span>' +
        this.fields[2].input.value + '</span> <span>' +
        this.fields[3].input.value + '</span> <span>' +
        this.fields[4].input.value + '</span> - <span>' +
        this.fields[5].input.value + '</span> - <span>' +
        this.fields[6].input.value + '</span> - <span>' +
        this.fields[7].input.value + '</span> - <span>' +
        this.fields[8].input.value + '</span>'
    },

    createPartNumber: function()
    {
        return 'M80 - ' +
        this.fields[0].input.value + ' ' +
        this.fields[1].input.value + ' ' +
        this.fields[2].input.value + ' ' +
        this.fields[3].input.value + ' ' +
        this.fields[4].input.value + ' - ' +
        this.fields[5].input.value + ' - ' +
        this.fields[6].input.value + ' - ' +
        this.fields[7].input.value + ' - ' +
        this.fields[8].input.value
    },

    createShortPartNumber: function()
    {
        return 'M80-' +
        this.fields[0].input.value +
        this.fields[1].input.value +
        this.fields[2].input.value +
        this.fields[3].input.value +
        this.fields[4].input.value + '-' +
        this.fields[5].input.value + '-' +
        this.fields[6].input.value + '-' +
        this.fields[7].input.value + '-' +
        this.fields[8].input.value
    },

    addPartNumber: function()
    {
        var partString = '<li id="partrow' + this.totalPartNumbers + '">' + this.formatPartNumber().toUpperCase() + ' <a href="" title="Remove this part number from your request" class="remove" id="removelink' + this.totalPartNumbers + '">Remove</a>';

	partString += '<a href="" title="Regenerate the image for this part" class="regenerate" id="regenerateLink' + this.totalPartNumbers + '">Regenerate Image</a>';
        
        var thisNumber = this.totalPartNumbers;
        var thisPart = this.createShortPartNumber().toUpperCase();

        new Ajax.Request('/ajax/checkpartnumber.php?part=' + this.createShortPartNumber(),
                         {
                            method: 'get',
                            onSuccess: function(transport)
                            {
                                if (transport.responseText == 'Found')
                                {
                                    var link = document.createElement('A');
                                    Element.extend(link);
                                    link.setAttribute('id', 'extralink' + this.totalPartNumbers);
                                    link.setAttribute('target', '_blank');
                                    link.setAttribute('href','/search/' + thisPart + '?ProductSearch=True');
                                    link.setAttribute('title', 'Click here to open a new browser window with this product');
                                    link.addClassName('extralink');
                                    
				    var img = document.createElement('img');
                                    img.setAttribute('src','/images/mix-tek/btn-view-drawing.png');
                                    img.setAttribute('alt','View drawing');
                                    link.appendChild(img);
                                    
									var thisname = 'partrow' + thisNumber;
                                    Element.extend($(thisname));
                                    $(thisname).appendChild(link);
                                }
                                else
                                {
                                    var link = document.createElement('A');
                                    Element.extend(link);
                                    link.setAttribute('id', 'extralink' + this.totalPartNumbers);
                                    link.setAttribute('target', '_blank');
                                    link.setAttribute('href','/contact/callback.html?query=I%20would%20like%20to%20inquire%20about%20' + thisPart + '%20found%20using%20the%20Datamate%20Mix-Tek%20builder');
                                    link.setAttribute('title', 'Click here to open a new browser window with a callback form for this product');
                                    link.addClassName('extralink');
                                    link.innerHTML =  'Request callback';
                                    var thisname = 'partrow' + thisNumber;
                                    Element.extend($(thisname));
                                    $(thisname).appendChild(link);
                                }
                            }});

        if (this.totalContacts(parseInt($('signal-quantity').value), parseInt($('special-before-quantity').value) + parseInt($('special-after-quantity').value)) > this.maxContacts)
        {
            partString += '<p>Special tooling may be required to manufacture this connector, as our standard tooling can accomodate a maximum size of 50 signal contacts.<br /> Special contacts take up the same number of contacts as <em>four</em> signal contacts.<br />If you provide your email address below we can contact you to discuss this connector.</p>'
        }

        partString += '<input type="hidden" name="part_numbers[]" value="' + this.createShortPartNumber() + '" id="part_number' + thisNumber + '" />'

        partString += '</li>'

        // Add it to the list
        new Insertion.Bottom('part-numbers', partString);

        this.totalPartNumbers++
    },

    removePartNumber: function(item)
    {
        if (confirm('Are you sure you wish to remove this part number?'))
        {
            item.remove()

            if ($('part-numbers').childElements().length < 1)
            {
                $('mixtek-part-list').hide()
            }

            this.totalPartNumbers--

            return true
        }
        else
        {
            return false
        }
    },

    highlighter: function(table)
    {
        table.observe('mouseover', function(event) {
            var row = Element.extend(Event.findElement(event, 'tr'))

            if (row.nodeName == 'TR')
            {
                if (row.siblings().length > 0)
                {
                    row.addClassName('over')
                }
            }
        })
        table.observe('mouseout', function(event) {
            var row = Element.extend(Event.findElement(event, 'tr'))

            if (row.nodeName == 'TR')
            {
                row.removeClassName('over')
            }
        })
    },

    addValue: function(event, target)
    {
        var row = Element.extend(Event.findElement(event, 'tr'))

        if (row.down('.value'))
        {
            value = row.down('.value').innerHTML
            value = this.sanitise(value)
            target.value = value
            this.focusNextField(target)
        }
    },

    padField: function(event)
    {
        var field = Event.element(event)
        var newValue = this.padValue(field.value, field.readAttribute('maxlength'))
        field.value = newValue
    },

    focusNextField: function(current)
    {
        var next = current.up('div.field').next('div.field')

        if (next)
        {
            next.down('input').focus()
        }
        else
        {
            current.next('div.helper').hide()
        }
    },

    validateField: function(input, value)
    {
        var validation = this.getValidation(input)
        var correct = false
        var errorMarker = input.next('span.error')

        validation.each(function(possible) {
            if (possible == value.toUpperCase() || value == '')
            {
                correct = true
            }
        })
        
        if (!correct)
        {
            errorMarker.show()
            this.addError(input.id)
        }
        else
        {
            errorMarker.hide()
            this.removeError(input.id)
        }

        // Special validations for specific fields
        if (input.id == 'jackscrew' || input.id == 'special-before-quantity' || input.id == 'special-after-quantity')
        {
            this.checkJackscrews(this.getSpecialTotal())
        }
    },

    validate: function()
    {
        this.empties = this.fields.findAll(function(field) {
            return field.input.value == ''
        })
        this.fields.each(function(field) {
            this.validateField(field.input, field.input.value)
        }.bind(this))

        if (this.hasEmpties())
        {
            this.empties.each(function(empty) {
                empty.input.next('span.error').show()
            })
        }
        else if (!this.hasEmpties() && !this.hasErrors())
        {
            this.hideMessage()
        }
    },

    checkSignalValues: function()
    {
        var style = $('signal-style')
        var quantity = $('signal-quantity')
        var finish = $('signal-finish')

	
        if (style.value != 0 && (quantity.value == 0 || finish.value == 0))
        {
            this.addError(style.id)
            style.next('span.error').show()
            this.showMessage('You must set the Signal Contact Style to zero if Signal Contact Quantity and/or Signal Contact Finish are set to zero.<br />Alternatively, make sure they all have values.')
            return false
        }
        else if (quantity.value != 0 && (style.value == 0 || finish.value == 0))
        {
            this.addError(quantity.id)
            quantity.next('span.error').show()
            this.showMessage('You must set the Signal Contact Quantity to zero if Signal Contact Style and/or Signal Contact Finish are set to zero.<br />Alternatively, make sure they all have values.')
            return false
        }
        else if (finish.value != 0 && (style.value == 0 || quantity.value == 0))
        {
            this.addError(finish.id)
            finish.next('span.error').show()
            this.showMessage('You must set the Signal Contact Finish to zero if Signal Contact Style and/or Signal Contact Quantity are set to zero.<br />Alternatively, make sure they all have values.')
            return false
        }
        else
        {
            this.hideMessage()
            return true
        }
    },

    checkSpecialValues: function()
    {
        var beforeQuantity = $('special-before-quantity')
        var beforeNumber = $('special-before-number')
        var afterQuantity = $('special-after-quantity')
        var afterNumber = $('special-after-number')

        if ((beforeQuantity.value != 0 && beforeNumber.value == 0) || (beforeQuantity.value == 0 && beforeNumber.value != 0))
        {
            if (beforeQuantity.value != 0 && beforeNumber.value == 0)
            {
                this.addError(beforeQuantity.id)
                beforeQuantity.next('span.error').show()
                this.showMessage('You must set the Quantity of Special Contacts to zero if the Special Contact Part Number is set to zero. Alternatively, make sure they both have values')
                return false
            }
            else if (beforeNumber.value != 0 && beforeQuantity.value == 0)
            {
                this.addError(beforeNumber.id)
                beforeNumber.next('span.error').show()
                this.showMessage('You must set the Part Number of Special Contacts to zero if the Special Contact Quantity is set to zero. Alternatively, make sure they both have values')
                return false
            }
            else
            {
                this.hideMessage()
                return true
            }
        }
        else if ((afterQuantity.value != 0 && afterNumber.value == 0) || (afterQuantity.value == 0 && afterNumber.value != 0))
        {
            if (afterQuantity.value != 0 && afterNumber.value == 0)
            {
                this.addError(afterQuantity.id)
                afterQuantity.next('span.error').show()
                this.showMessage('You must set the Quantity of Special Contacts to zero if the Special Contact Part Number is set to zero. Alternatively, make sure they both have values')
                return false
            }
            else if (afterNumber.value != 0 && afterQuantity.value == 0)
            {
                this.addError(afterNumber.id)
                afterNumber.next('span.error').show()
                this.showMessage('You must set the Part Number of Special Contacts to zero if the Special Contact Quantity is set to zero. Alternatively, make sure they both have values')
                return false
            }
            else
            {
            	this.hideMessage()
            	return true
            }
        } 
        else 
        {
        	this.hideMessage()
        	return true
    	}
    },
    
    checkJackscrewSpecial: function()
    {
    	var jackscrew = $('jackscrew')
    	var bNumber = $('special-before-number')
    	 
    	if (jackscrew.value == 'M5' || jackscrew.value == 'M7' || jackscrew.value == 'MD')
    	{
    		if (bNumber.value == '311' || bNumber.value == '312' || bNumber.value == '331' || bNumber.value == '332')
    		{
    			this.addError(jackscrew.id)
                jackscrew.next('span.error').show()
    			this.addError(bNumber.id)
                bNumber.next('span.error').show()
                this.showMessage('You cannot use a special contact part number of 311, 312, 331 or 332 with M5, M7 or MD jackscrews')
                return false
    		}
    		else
    		{
    			this.hideMessage()
        		return true
    		}
    	}
    	else if (jackscrew.value == 'M2' || jackscrew.value == 'M3')
    	{
    		if (bNumber.value == '313' || bNumber.value == '314' || bNumber.value == '333' || bNumber.value == '334')
    		{
    			this.addError(jackscrew.id)
                jackscrew.next('span.error').show()
    			this.addError(bNumber.id)
                bNumber.next('span.error').show()
                this.showMessage('You cannot use a special contact part number of 313, 314, 333 or 334 with M2 or M3 jackscrews')
                return false
    		}
    		else
    		{
    			this.hideMessage()
        		return true
    		}
    	}
    	else
    	{
    		this.hideMessage()
    		return true
    	}
    },
    
    totalContacts: function(signal, special)
    {
        return (special * 4) + signal;
    },

    sanitise: function(value)
    {
        return value.strip().stripTags().stripScripts()
    },

    padValue: function(value, finalLength)
    {	
    	if (!isNaN(value))
        {	
    		newValue = parseInt(Number(value)).toPaddedString(finalLength);
    		
            if (!isNaN(newValue))
            {
            	return newValue;
            }
            else
            {
                return value;
            }
        }
        else
        {
            return value;
        }
    },

    getValidation: function(input)
    {
        return this.fields.find(function(field) {
            return field.input.id == input.id
        }).validation
    },

    updateChoices: function(field)
    {	
    	if (field.id == 'gender')
        {
            this.getSignalStyles($('gender').value)

            if ($('signal-style').value != '')
            {
                this.getSignalFinishes($('gender').value, $('signal-style').value)
                this.getJackscrew($('gender').value, $('signal-style').value)
                this.getSpecial($('gender').value, $('signal-style').value)
            }
        }
        if (field.id == 'signal-style')
        {
            this.getSignalFinishes($('gender').value, $('signal-style').value)
            this.getJackscrew($('gender').value, $('signal-style').value)
            this.getSpecial($('gender').value, $('signal-style').value)
        }
        if (field.id == 'jackscrew')
        {
        	this.getSpecial($('gender').value, $('signal-style').value)
        }
    },

    getSignalStyles: function(gender)
    {
        if (gender.blank())
        {
            $('signal-style-values').down('table').down('tbody').update('<tr><th colspan="2">Please make sure you have specified a <em>Gender</em></th></tr>')
        }
        else
        {
            if (gender == 4)
            {
                var allowedSignalStyles = this.restrictions.female.collect(function(restriction) {
                    return restriction.id
                })
            }
            else if (gender == 5)
            {
                var allowedSignalStyles = this.restrictions.male.collect(function(restriction) {
                    return restriction.id
                })
            }
            else
            {
                return
            }

            var signalStyles = this.contacts.signalStyle.findAll(function(style) {
                return allowedSignalStyles.find(function(allowedSignalStyle) {
                    return allowedSignalStyle == style.id
                })
            })

            var signalStyleHTML = ''
            signalStyles.each(function(signalStyle) {
                signalStyleHTML += '<tr><th class="value">' + signalStyle.id + '</th><td>' + signalStyle.detail + '</td></tr>'
            })

            $('signal-style-values').down('table').down('tbody').update(signalStyleHTML)

            if (!this.hasValue($('signal-style').value, allowedSignalStyles))
            {
                $('signal-style').value = ''
            }
        }
    },

    getSignalFinishes: function(gender, signalStyle)
    {
        if (gender.blank() || signalStyle.blank())
        {
            $('signal-finish-values').down('table').down('tbody').update('<tr><th colspan="2">Please make sure you have specified a <em>Gender</em> and <em>Signal Contact Style</em></th></tr>')
        }
        else
        {
            if (gender == 4 && signalStyle != '')
            {
                var allowedSignalFinishes = this.restrictions.female.find(function(restriction) {
                    return restriction.id == signalStyle
                }).finish
            }
            else if(gender == 5 && signalStyle != '')
            {
                var allowedSignalFinishes = this.restrictions.male.find(function(restriction) {
                    return restriction.id == signalStyle
                }).finish
            }
            else
            {
                return
            }

            var signalFinishes = this.contacts.signalFinish.findAll(function(finish) {
                return allowedSignalFinishes.find(function(allowedSignalFinish) {
                    return allowedSignalFinish == finish.id
                })
            })

            var signalFinishHTML = ''
            signalFinishes.each(function(signalFinish) {
                signalFinishHTML += '<tr><th class="value">' + signalFinish.id + '</th><td>' + signalFinish.detail + '</td></tr>'
            })

            $('signal-finish-values').down('table').down('tbody').update(signalFinishHTML)

            if (!this.hasValue($('signal-finish').value, allowedSignalFinishes))
            {
                $('signal-finish').value = ''
            }
        }
    },

    getJackscrew: function(gender, signalStyle)
    {
        if (gender.blank() || signalStyle.blank())
        {
            $('jackscrew-values').down('table').down('tbody').update('<tr><th colspan="2">Please make sure you have specified a <em>Gender</em> and <em>Signal Contact Style</em></th></tr>')
        }
        else
        {
            if (gender == 4)
            {
                var allowedJackscrews = this.restrictions.female.find(function(restriction) { 
			return restriction.id  == signalStyle.toUpperCase(); 
		}).jackscrew   
            }
            else if (gender == 5)
            {
                var allowedJackscrews = this.restrictions.male.find(function(restriction) { 
			return restriction.id == signalStyle.toUpperCase(); 
		}).jackscrew	
	    }
            else
            {
                return
            }

            var jackscrews = this.contacts.jackscrew.findAll(function(jackscrew) {
                return allowedJackscrews.find(function(allowedJackscrew) {
                    return allowedJackscrew == jackscrew.id
                })
            })
	    
	    var jackscrewHTML = ''
            jackscrews.each(function(jackscrew) {
                jackscrewHTML += '<tr><th class="value">' + jackscrew.id + '</th><td>' + jackscrew.detail + '</td></tr>'
            })

            $('jackscrew-values').down('table').down('tbody').update(jackscrewHTML)

            if (!this.hasValue($('jackscrew').value, allowedJackscrews))
            {
                $('jackscrew').value = ''
            }
        }
    },

    getSpecial: function(gender, signalStyle)
    {
        if (gender.blank() || signalStyle.blank())
        {
            $('special-before-number-values').down('table').down('tbody').update('<tr><th colspan="2">Please make sure you have specified a <em>Gender</em> and <em>Signal Contact Style</em></th></tr>')
            $('special-after-number-values').down('table').down('tbody').update('<tr><th colspan="2">Please make sure you have specified a <em>Gender</em> and <em>Signal Contact Style</em></th></tr>')
        }
        else
        {
            if (gender == 4)
            {
                var allowedSpecialContacts = this.restrictions.female.find(function(restriction) {
                    return restriction.id == signalStyle
                }).special
            }
            else if (gender == 5)
            {
            	var allowedSpecialContacts = this.restrictions.male.find(function(restriction) { 
            		return restriction.id == signalStyle 
            	}).special
            	
            	var js = $('jackscrew').value
            	var js = js.toUpperCase();
            	
            	if (js == 'M5' || js == 'M7' || js == 'MD')
            	{
            		allowedSpecialContacts.remove('311')
            		allowedSpecialContacts.remove('312')
            		allowedSpecialContacts.remove('331')
            		allowedSpecialContacts.remove('332')
            	} 
            	else if (js == 'M2' || js == 'M3')
            	{
            		allowedSpecialContacts.remove('313')
            		allowedSpecialContacts.remove('314')
            		allowedSpecialContacts.remove('333')
            		allowedSpecialContacts.remove('334')
            	}
            }
            else
            {
                return
            }

            var specials = this.contacts.special.findAll(function(special) {
                return allowedSpecialContacts.find(function(allowedSpecial) {
                    return allowedSpecial == special.id
                })
            })

            var specialHTML = ''
            specials.each(function(special) {
                specialHTML += '<tr><th class="value">' + special.id + '</th><td>' + special.detail + '</td></tr>'
            })

            $('special-before-number-values').down('table').down('tbody').update(specialHTML)
            $('special-after-number-values').down('table').down('tbody').update(specialHTML)

            if (!this.hasValue($('special-before-number').value, allowedSpecialContacts))
            {
                $('special-before-number').value = ''
            }
            if (!this.hasValue($('special-after-number').value, allowedSpecialContacts))
            {
                $('special-after-number').value = ''
            }
        }
    },

    getSpecialTotal: function()
    {
        var specialBefore = $('special-before-quantity').value
        var specialAfter = $('special-after-quantity').value

        specialBefore = (specialBefore != '' && !isNaN(specialBefore)) ? parseInt(specialBefore) : 0
        specialAfter = (specialAfter != '' && !isNaN(specialAfter)) ? parseInt(specialAfter) : 0

        return specialBefore + specialAfter
    },

    hasValue: function(value, collection)
    {
        var isPresent
        collection.each(function(item) {
            if (item == value)
            {
                isPresent = true
                return
            }
        })
        return isPresent
    },

    getHelper: function(field)
    {
        return field.next('div.helper')
    },

    mouseWithinHelper: function(helper, event)
    {
        if (Position.within(helper, Event.pointerX(event), Event.pointerY(event)))
        {
            return true
        }
        else
        {
            return false
        }
    },

    mouseWithinField: function(field, event)
    {
        if (Position.within(field, Event.pointerX(event), Event.pointerY(event)))
        {
            return true
        }
        else
        {
            return false
        }
    },

    hideOtherHelpers: function()
    {
        if (this.currentHelper)
        {
            var others = this.helpers.findAll(function(helper) {
                return helper.id != this.currentHelper.id
            }.bind(this))

            others.each(Element.hide.bind(this))
        }
        else
        {
            return false
        }
    },

    showHelper: function(event, helper)
    {
        this.updateChoices(this.currentField)
        this.currentField = Event.element(event)
        if (!helper.visible())
        {
            helper.show()
            this.currentHelper = helper
            this.hideOtherHelpers()
        }
    },

    hideHelper: function(event)
    {
        if (Event.findElement(event, 'input') == document)
        {
            if (Event.findElement(event, 'div') == document)
            {
                this.currentHelper.hide()
            }
            else
            {
                if (!Event.findElement(event, 'div').hasClassName('helper') && !Event.findElement(event, 'div').hasClassName('scroller'))
                {
                    this.currentHelper.hide()
                }
            }
        }
    },

    checkJackscrews: function(specialQuantity)
    {
        var warning = $('jackscrew-warning')

        if (this.jackscrewWarning(specialQuantity))
        {
            warning.show()
        }
        else
        {
            warning.hide()
        }

        warning.down('a.dismiss').observe('click', function(event) {
            warning.hide()
            this.disabledJackscrewWarning = true
            Event.stop(event)
        }.bind(this))
    },

    jackscrewWarning: function(specialQuantity)
    {
        if (specialQuantity > 0 && $('jackscrew').value == 0)
        {
            return true
        }
        else
        {
            return false
        }
    },

    addError: function(id)
    {
        return this.errors.push(id)
    },

    removeError: function(id)
    {
        return this.errors = this.errors.without(id)
    },

    addEmpty: function(id)
    {
        return this.empties.push(id)
    },

    removeEmpty: function(id)
    {
        return this.errors = this.errors.without(id)
    },

    hasEmpties: function(fields)
    {
        return (this.empties.length > 0) ? true : false
    },

    hasErrors: function()
    {
        return (this.errors.length > 0) ? true : false
    },

    showMessage: function(message)
    {
        $('message').update(message)
        $('message').show()
    },

    hideMessage: function()
    {
        $('message').hide()
    },

    getPreviewImage: function(part)
    {
	var part = part
	var ajax = new Ajax.Request('/ajax/generate_mixtek_preview.php?part=' + part,{
            method: 'get',
            onSuccess: function(transport){
                if (!$('mixtek_preview_img'))
                {
                    var img = document.createElement('img');
                    img.setAttribute('id', 'mixtek_preview_img');
                    $('mixtek_preview').appendChild(img);
                }
                if ($('mixtek_preview_error'))
                {
                    $('mixtek_preview_error').remove();
                }
                var img_src = transport.responseText;
                $('mixtek_preview_img').src = '/images/mix-tek/mix_tek_previews/' + part + '.jpg';
                $('mixtek_preview').style.display = 'block';
                $('mixtek_preview_img').alt = "Preview of " + part;
				
                if ($('mixtek_preview_pdf'))
				{
                	$('mixtek_preview_pdf').remove()
				}	
                
				var a = document.createElement('a');
				
				a.setAttribute('id', 'mixtek_preview_pdf');
				a.setAttribute('href', 'mixtekdatamate.html?id=' + part);
				a.appendChild(document.createTextNode('Download a pdf document of image '));
				$('mixtek_preview').appendChild(a);	
				
            },
            onFailure: function(transport){
                if ($('mixtek_preview_img'))
                {
                    $('mixtek_preview_img').remove();
                }
                if ($('mixtek_preview_error'))
                {
                    $('mixtek_preview_error').remove();
                }
                var p = document.createElement('p');
                p.setAttribute('id', 'mixtek_preview_error');
                p.appendChild(document.createTextNode('There was an error generating the preview image for ' + part));
                $('mixtek_preview').appendChild(p);
            }
        });
    },

    generate: function(event)
    {	

    	this.validate()
    	
    	if (!this.checkSignalValues())
        {
        	Event.stop(event)
        	return false
        }
	
        if (!this.checkSpecialValues())
        {
        	Event.stop(event)
        	return false
        }
        
        if (!this.checkJackscrewSpecial())
        {
        	Event.stop(event)
        	return false
        }
        
        if (this.totalContacts(parseInt($('signal-quantity').value), parseInt($('special-before-quantity').value) + parseInt($('special-after-quantity').value)) > this.maxContacts)
        {
        	this.showMessage('You can only have a maximum of 50 signal contact. Each special conatct counts as 4. Please correct these errors')
        	Event.stop(event)
        	return false
        }

        if (this.hasErrors())
        {
            this.showMessage('There are some errors in the form. Please make sure you correct them all.')
            Event.stop(event)
        }
        else if (this.hasEmpties())
        {
            if (!$('message').visible())
            {
                this.showMessage('There are some empty fields. Please make sure you fill them out.')
            }
            Event.stop(event)
        }
        else
        {
            this.disabledJackscrewWarning = false // Make sure the jackscrew warning will be there next time
            this.addPartNumber()
            $('mixtek-part-list').show()
            var part = this.createShortPartNumber();
            this.getPreviewImage(part);
            Event.stop(event)
        }

        this.currentHelper.hide()
    }

}

