//----------------------------------------------------------------------------
// Objects

var products = new Array();

/**
 * Product object
 *
 * @param type the core product code - [ PDF | REP | GRA ]
 * @param license the license (annual or perpetual) [ A | P ]
 * @param subtype the set variation flags in alphabetical order - [ E | S | V ]{1,3}
 * @param description the text description
 * @p1 pricing for 1 unit
 * @p5 pricing for 5 units
 * @p10 pricing for 10 units
 */
function Product(description, type, license, subtype, p1, p5, p10) {
    var prices = new Array(p1, p5, p10);

    this.getCode = function() {
        return type+"."+license+"."+subtype;
    };

    this.getType = function() {
        return type;
    };

    this.getDescription = function() {
        return description;
    };

    this.getPrice = function(num) {
        var types = [1, 5, 10];
        var total = 0;
        for (var type=types.length;type>=0;type--) {
            if (num>=types[type]) {
                var thisnum = ((num-(num%types[type]))/types[type]);
                total += prices[type] * thisnum;
                num = num%types[type];
            }
        }
        return total;
    };
}

{
    products.push(new Product("PDF Library Standard",          "PDF2", "P", "S",   850, 3300, 5500));
    products.push(new Product("PDF Library Extended",          "PDF2", "P", "ES",  1430, 5500, 7700));
    products.push(new Product("PDF Library Extended + Viewer", "PDF2", "P", "ESV", 1830, 7000, 10350));

    products.push(new Product("Report Generator",                   "REP1", "P", "S",   1650, 6050, 8800));
    products.push(new Product("Report Generator Extended",          "REP1", "P", "ES",  2200, 8250, 11000));
    products.push(new Product("Report Generator Extended + Viewer", "REP1", "P", "ESV", 2600, 7000, 10350));

    products.push(new Product("Graph Library",                      "GRA2", "P", "S", 800, 3000, 4500));
    products.push(new Product("PDF Viewer",                         "PDF2", "P", "EV", 400, 1500, 2650));
}

//-------------------------------------------------------------------------
// Download form
//-------------------------------------------------------------------------

/**
 * Confirm the details on the download form.
 * Public, called from products/postdownload.jsp
 */
function submitDownloadForm(form) {
    if (!form.agreed.checked) {
        alert("Please tick the box to accept the license agreement");
        return false;
    } else if (!checkEmail(form.email.value)) {
        alert("Please enter a valid email address, or leave it blank (it's optional)");
        return false;
    } else {
        return true;
    }
}

//-------------------------------------------------------------------------
// Not cleaned up functions
//-------------------------------------------------------------------------

/**
 * Calculate the prices on teh reseller quote form
 * Public, called from reseller/quote.jsp
 */
function calculateResellerQuoteForm(f) {
    var num="", total="", supporttotal="", product;
    if (f.details_1.selectedIndex>0) {
	num = f.quantity_1.value;
	if (num=="" || num=="0") num=1;

	var product;
	var option = f.details_1.options[f.details_1.selectedIndex];
	for (var i=0;i<products.length;i++) {
	    if (products[i].internalcode == option.value) {
	        product = products[i];
		break;
	    }
	}
	total = calcPrice(num, product) * 0.9;

	if (f.details_2.selectedIndex>0) {
	    option = f.details_2.options[f.details_2.selectedIndex];
	    if (product.internalcode.indexOf(option.value)==0) {
	        supporttotal = total*0.2 > 400 ? total*0.2 : 400;
	    }
	}
    }
    f.amount_1.value = total;
    f.amount_2.value = supporttotal;
    f.quantity_1.value = num;
    f.quantity_2.value = supporttotal=="" ? "" : "1";
}

/**
 * Submit the reseller quote form.
 * Public, called from reseller/quote.jsp
 */
function submitResellerQuoteForm(f) {
    var out="";
    if (f.address.value=="") out+="Must enter a recipient\n";
    if (f.subject.value=="") out+="Must enter a subject\n";
    if (f.contact.value=="" || !checkEmail(f.contact.value)) {
	out+="Must enter a valid email address\n";
    }
    if (f.details_1.selectedIndex<1 && f.details_2.selectedIndex<1 && f.details_3.value=="" && f.details_4.value=="" && f.details_5.value=="") {
	out+="Must enter at least one item to quote for\n";
    }

    if (out!="") {
	alert(out);
	return false;
    } else {
	// Set the values of the drop down lists to their text values.
	if (f.details_1.selectedIndex>0) {
	    f.details_1.options[f.details_1.selectedIndex].value = f.details_1.options[f.details_1.selectedIndex].text;
	}
	if (f.details_2.selectedIndex>0) {
	    f.details_2.options[f.details_2.selectedIndex].value = f.details_2.options[f.details_2.selectedIndex].text;
	}
        return true;
    }
}

/**
 * Public, called from reseller/register.jsp
 */
function submitResellerMail(f) {
    if(!(f.t12.checked)) {
	alert("Please confirm you have read the License Terms and Conditions");
	return;
    }

    if((f.t9.value == "" || f.t10.value == "") || (f.t9.value != f.t10.value)) {
	alert("Please supply and confirm your password");
	return;	
    }

    if (f.t7.value == "" || checkEmail(f.t7.value) == false) {
	alert("Please supply an email address");
	return;	
    }

    body =  "\nCompany: " + f.t1.value
    + " \nContact Name: " + f.t2.value
    + " \nCompany Role: " + f.t3.value
    + " \nCompany Address: " + f.t4.value
    + " \nCountry: " + f.t5.options[f.t5.selectedIndex].value
    + " \nContact Tel: " + f.t6.value
    + " \nFax: " + f.t11.value
    + " \nEmail: " + f.t7.value
    + " \nWebsite: " + f.t8.value
    + " \nPassword: " + f.t9.value;

    emailURL = "mailto:reseller@big.faceless.org?subject=Reseller%20Registration"
	+ "&body=" + escape(body);	

    window.location = emailURL;	
}

//----------------------------------------------------------------------------------

function isJavaWebStartInstalled() {
    var webstart = false;
    if (navigator.mimeTypes && navigator.mimeTypes.length) {
        if (navigator.mimeTypes["application/x-java-jnlp-file"]) {
            webstart = true;
        } else {
            webstart = false;
        }
    } else {    // Microsoft Browsers
        try {
            var test = new ActiveXObject("JavaWebStart.isInstalled");
            webstart = true;
         } catch(e) {
            webstart = false;
        }
    }
    return webstart;
}

//----------------------------------------------------------------------------------
// Sales form handling
//----------------------------------------------------------------------------------
// Helper methods
//----------------------------------------------------------------------------------

/**
 * Confirm the email address is value or empty
 */
function checkEmail(str) {
    if (str==null || str.length==0) return true;    // empty address is OK

    var lat=str.indexOf("@");
    var len=str.length;
    var ldot=str.indexOf(".");
    var ret=true;

    if (str.indexOf("@")==-1) ret=false;
    if (str.indexOf("@")==-1 || str.indexOf("@")==0 || str.indexOf("@")==len) ret=false;
    if (str.indexOf(".")==-1 || str.indexOf(".")==0 || str.indexOf(".")==len) ret=false;
    if (str.indexOf("@",(lat+1))!=-1) ret=false;
    if (str.substring(lat-1,lat)=="." || str.substring(lat+1,lat+2)==".") ret=false;
    if (str.indexOf(".",(lat+2))==-1) ret=false;
    if (str.indexOf(" ")!=-1) ret=false;
    return ret;
}

/**
 * Check the quantity of items to ensure that they are rounded to the nearest
 * cheapest option.
 * @param q the quantity - a number (eg 4);
 * @return the updated quantity (eg 5);
 */
function checkQuantity(q) {
    var old = q;
    if (q%10>7) {
      var newQ = parseInt(q) + parseInt((10-q%10));
       alert("Due to our pricing structure it's cheaper to buy "+ newQ +" copies than "+q+".\nWe've changed this over for you automatically");
       q += (10-q%10);
    } else if (q%5==4) {
        var newQ = parseInt(q) + parseInt(5-q%5);
	alert("Due to our pricing structure it's cheaper to buy "+ newQ +" copies than "+q+".\nWe've changed this over for you automatically");
	q += (5-q%5);
    }
    return q;
}

/**
 * Return a Product object matching the specified code, or null if none match
 * @param code the product code, eg "PDF.P.ES"
 */
function getProductFromCode(code) {
    for (var i=0;i<products.length;i++) {
        if (products[i].getCode()==code) {
            return products[i];
        }
    }
    return null;
}

/**
 * Format the supplied numeric value as $#0.00
 */
function formatUSD(val) {
    return "$" + formatTo2Decimals(val);
}

/**
 * Format the supplied numeric value as #0.00
 */
function formatTo2Decimals(val) {
    if (val==0) return "0.00";
    var x = "" + Math.round(val*100);
    return x.substr(0, x.length-2)+"."+x.substr(x.length-2);
}

/**
 * Test if this country requires VAT to be charged
 * @param country the 2 letter ISO-3166 country code (uppercase)
 */
function isVATRequired(country) {
    var vatcountries = ["BE", "BG", "CZ", "DK", "DE", "EE", "IE", "EL", "ES", "FR", "IT", "CY", "LV", "LT", "LU", "HU", "MT", "NL", "AT", "PL", "PT", "RO", "SI", "SK", "FI", "SE", "UK", "JE", "GG", "IM"];
    for (var i=0;i<vatcountries.length;i++) {
        if (vatcountries[i]==country) return true;
    }
    return false;
}
	
/**
 * Validate the VAT number for the country passed in
 * @param country the 2 letter ISO-3166 country code (uppercase)
 * @param vat the VAT code (case sensitive, should be uppercase)
 * @return true if it's OK or VAT isn't required, false (after an alert) if it's not
 */
function isValidVATNumber(country, vat, name) {
    var c2 = country;
    if (!isVATRequired(country)) {
        return true;                    // don't care - VAT not applicable
    } else {
        var msg = "";
        if (c2=="AT") {
            if (!/^U[0-9]{8}$/.test(vat)) msg="9 chars and begin with 'U'";
        } else if (c2=="CY") {
            if (!/^[0-9]{8}X$/.test(vat)) msg="8 digits followed by 'X'";
        } else if (c2=="CZ") {
            if (!/^[0-9]{8}[0-9]?[0-9]?$/.test(vat)) msg="8, 9 or 10 digits - if 11, 12 or 13 supplied, delete the first 3";
        } else if (c2=="FR") {
            if (!/^[ABCDEFGHJKLMNPQRSTUVWXYZ0-9]{2}[0-9]{9}$/.test(vat)) msg="11 chars, the last nine of them digits";
        } else if (c2=="DE" || c2=="PT" || c2=="EE" || c2=="BE") {
            if (!/^[0-9]{9}$/.test(vat)) msg="9 digits";
        } else if (c2=="EL") {
            if (!/^[0-9]{9}$/.test(vat)) msg="9 digits - if 8 supplied, prefix with 0";
        } else if (c2=="HU" || c2=="LU" || c2=="MT" || c2=="SI" || c2=="DK" || c2=="FI") {
            if (!/^[0-9]{8}$/.test(vat)) msg="8 digits";
        } else if (c2=="IE") {
            if (!/^[0-9]{7}[A-Z]$/.test(vat) && !/^[0-9][A-Z][0-9]{5}[A-Z]$/.test(vat)) msg="8 characters, all digits except for last or second and last";
        } else if (c2=="IT" || c2=="LV") {
            if (!/^[0-9]{11}$/.test(vat)) msg="11 digits";
        } else if (c2=="PL" || c2=="SK") {
            if (!/^[0-9]{10}$/.test(vat)) msg="10 digits";
        } else if (c2=="NL") {
            if (!/^[0-9]{9}B[0-9][0-9]$/.test(vat)) msg="12 digits, with the tenth always a 'B'";
        } else if (c2=="ES") {
            if (!/^[A-Z][0-9]{8}$/.test(vat) && !/^[0-9]{8}[A-Z]$/.test(vat) && !/^[A-Z][0-9]{7}[A-Z]$/.test(vat)) msg="10 characters, all numbers except for first, last or both";
        } else if (c2=="SE") {
            if (!/^[0-9]{10}01$/.test(vat)) msg="12 digits ending in '01'";
        } else if (c2=="LT") {
            if (!/^[0-9]{9}$/.test(vat) && !/^[0-9]{12}$/.test(vat)) msg="9 or 12 digits";
        } else if (c2=="UK" || c2=="GG" || c2=="JE" || c2=="IM") {
            if (!/^[0-9]{9}$/.test(vat) && !/^[0-9]{12}$/.test(vat) && !/^GD[0-9]{3}$/.test(vat) && !/^HA[0-9]{3}$/.test(vat)) msg="9 or 12 digits";
        } else {
            msg="Unknown problem - country='"+country+"' value='"+c2+"'";
        }

        if (vat.length==0) {
            return confirm("VAT number for "+name+" should be "+msg+" - click Cancel to go back, OK to continue");
        } else if (msg) {
            alert("VAT number for "+name+" must be "+msg);
            return false;
        } else {
            return true;
        }
    }
}

//----------------------------------------------------------------------------------
// Stage 1 - SalesItemForm
//----------------------------------------------------------------------------------

/**
 * Called when a field is updated in the sale form. Updates the correct
 * elements on the page and sets the values of the "saledecription" field
 * to a JSON object describing the sale as a whole
 */
function updateSaleItemForm(form) {
    var productcode = form.product.options[form.product.selectedIndex].value;
    var coreproductcode = productcode.split(".")[0];
    var numprod = form.numprodcpus.value = checkQuantity(form.numprodcpus.value * 1);
    var numother  = form.numothercpus.value * 1;
    var support  = form.support.checked;
    if (numprod<0) numprod=0;
    if (numother<0) numother=0;
    
    if ((numother>0) && (numprod == 0)) {
      alert("You must select production licences in order to buy non-production licences");
      numother=0;
      form.numothercpus.value = "0";
    }

    if ((support) && (0==numprod)) {
      alert("You must select production licences in order to buy support");
      form.support.checked = false;
    }

    var product = getProductFromCode(productcode);

    var prodcpuamount = product.getPrice(numprod);
    var othercpuamount = numother * 200;
    var supportamount = support ? Math.max(400, (prodcpuamount + othercpuamount) * 0.2) : 0;
    var totalamount = prodcpuamount+othercpuamount+supportamount;
    var vatamount = Math.round((prodcpuamount+othercpuamount+supportamount)*getVatRate()*100)/100;

    document.getElementById("prodcpuprice").innerHTML = formatUSD(prodcpuamount);
    document.getElementById("othercpuprice").innerHTML = formatUSD(othercpuamount);
    document.getElementById("supportprice").innerHTML = formatUSD(supportamount);
    document.getElementById("totalprice").innerHTML = formatUSD(totalamount);

    var response = { "type": productcode, "total": totalamount, "products": [ ] };
    response.products.push({ "code": productcode, "name": product.getDescription(), "quantity": numprod, "price": prodcpuamount } );
    var verfreecoreproductcode = coreproductcode.substring(0, coreproductcode.length-1);
    if (numother>0) {
        response.products.push({ "code": "QA."+verfreecoreproductcode, "name": "Development/QA Licenses", "quantity": numother, "price": othercpuamount });
    }
    if (support) {
        response.products.push({ "code": "SUP."+verfreecoreproductcode, "name": "Technical Support", "quantity": 1, "price": supportamount });
    }
    response.products.push({ "code": "VAT", "name": "VAT @ "+getVatRateString(), "quantity": 1, "price": vatamount });
    form.saledescription.value = JSON.stringify(response);
}

function submitSaleItemForm(form, a, t, method) {
    if (method=="secpay") {
        location.href="secpaystep1.jsp?product="+escape(form.saledescription.value);
    }
}

//----------------------------------------------------------------------------------
// Stage 2 - SalesPersonForm
//----------------------------------------------------------------------------------

/**
 * Update the SalePerson form. Called on every change of one of its fields.
 * Updates both the visible product summary table, and the hidden fields
 * "bfoorder" and "amount", containing the JSON-encoded order summary and gross
 * amount respectively.
 *
 * @param form the form
 * @param targetid the table containing the text description of the sale.
 */
function updateSalePersonForm(form, targetid) {
    var country = form.bill_country.value;
    var countryname = form.bill_country.options[form.bill_country.selectedIndex].text;
    order.needvat = isVATRequired(country);
    form.vat_number.disabled = !order.needvat;
    if (order.needvat) {
        order.hasvat = country!='UK' && form.vat_number.value.length > 0 && isValidVATNumber(country, form.vat_number.value, countryname);
    }

    var html = "";
    var total = 0;
    var tgtObj = document.getElementById(targetid);
    var numRows = tgtObj.rows.length;
    for (var r=0;r<numRows;r++) {
      tgtObj.deleteRow(0);
    }

    for (var i=0;i<order.products.length;i++) {
        order.products[i].include = (order.needvat && !order.hasvat) || order.products[i].code!='VAT';
        if (order.products[i].include) {
            // dynamically add a row and cells to table - DON'T use innerHTML, IE craps out
            var newRow = tgtObj.insertRow(-1);
            var cell1 = newRow.insertCell(0);
            cell1.innerHTML = order.products[i].name;
            var cell2 = newRow.insertCell(1);
            cell2.innerHTML = order.products[i].quantity;
            var cell3 = newRow.insertCell(2);
            cell3.innerHTML = formatUSD(order.products[i].price);

            total += order.products[i].price * 1;
        }
    }

    // Add Total row
    var newRow = tgtObj.insertRow(-1);
    var cell1 = newRow.insertCell(0); // TODO Make colspan=2
    cell1.innerHTML = "<b>Total</b>";
    var cellHidden = newRow.insertCell(1);
    var cell2 = newRow.insertCell(2);
    cell2.innerHTML = formatUSD(total);

    // N.B. We store "our" order details in JSON format in "bfoorder" field. "order" field has SECPay details in it
    form.bfoorder.value = JSON.stringify(order);
    form.amount.value = formatTo2Decimals(total);
//    alert(form.order.value);
}

/**
 * Verify the SalePerson Form - return true if it's complete, false otherwise.
 * @param form the form
 */
function validateSalePersonForm(form) {
    if (form.bill_country.selectedIndex == 0) {     // user hasn't selected a country
        return false;
    } else if (form.bill_name.value == "") {        // user hasn't entered a name
        return false;
    } else if (form.bill_post_code.value == "") {   // user hasn't entered a postcode
        return false;
    } else if (form.bill_addr_1.value == "") {      // user hasn't entered an address line 1
        return false;
    } else if (form.bill_email.value == "" || !checkEmail(form.bill_email.value)) {       // user hasn't entered an email
        return false;
    } else if (form.bill_city.value == "") {        // user hasn't entered a city
        return false;
    }

    var shipCheck = form.shipCheck;
    if (shipCheck.checked) {
        form.ship_name.value = form.bill_name.value;
        form.ship_company.value = form.bill_company.value;
        form.ship_addr_1.value = form.bill_addr_1.value;
        form.ship_addr_2.value = form.bill_addr_2.value;
        form.ship_state.value = form.bill_state.value;
        form.ship_city.value = form.bill_city.value;
        form.ship_post_code.value = form.bill_post_code.value;
        form.ship_tel.value = form.bill_tel.value;
        form.ship_email.value = form.bill_email.value;
        form.ship_country.selectedIndex = form.bill_country.selectedIndex;
    } else {
        // user has chosen separate shipping - check they have entered basic shipping details too
        if (form.ship_name.value == "") {                   // user hasn't entered a name
            return false;
        } else if (form.ship_country.selectedIndex == 0) {  // user hasn't selected a country
            return false;
        } else if (form.ship_post_code.value == "") {       // user hasn't entered a postcode
            return false;
        } else if (form.ship_addr_1.value == "") {          // user hasn't entered an address line 1
            return false;
        } else if (form.ship_email.value == "" || !checkEmail(form.ship_email.value)) {           // user hasn't entered an email
            return false;
        } else if (form.ship_city.value == "") {            // user hasn't entered a city
            return false;
        }
    }
    return true;
}

/**
 * Return true if the SalePerson form should be submitted, false otherwise
 * @param form the form
 */
function submitSalePersonForm(form) {
    if (!validateSalePersonForm(form)) {
        alert("There is some information missing.\nPlease ensure that you have entered information for all (*) fields.");
        return false;
    } else if (order.needvat && !order.hasvat) {
        return confirm("Please note:\nAs you are purchasing from an EU country and not using a VAT number we will have to add VAT to your order at "+getVatRateString()+"\nClick OK to proceed or Cancel to abort.");
    } else {
        return true;
    }
}

function getVatRate() {
    var now = new Date().getTime();
    return now < 1228089600000 || now >= 1262304000000 ? 0.175 : 0.15;
}

function getVatRateString() {
    var now = new Date().getTime();
    return now < 1228089600000 || now >= 1262304000000 ? "17.5%" : "15%";
}
