﻿// This is open source, based on GNU's General Public License (GPL).
// See http://www.gnu.org/copyleft for further details about the GNU GPL.



// Order-form configuration items
var calendarOmitCharge = false;
var calendarOmitDeliveryFee = false;
var calendarOrderEmail = "fotograf" + at + GetDomain( document.location.toString() );
var calendarOrderSubject = "Kalenderbestellung";
var calendarReferenceFieldId = "reference-field";
var calendarNormalBackgroundColor = "";
var calendarErrorBackgroundColor = "#FFE0E0";
var calendarOrderCurrency = "Euro";
var calendarDecimalPoint = ",";
var calendarItemWidth = 225 + 75;
var calendarItemPadding = 40;

// Templates for order-form components (refers to classes of 'content.css')
var calendarUsageNotes =
    "<p>Mit Hilfe dieses Formulars k"+oe+"nnen Sie den Fotokalender mit Bildern der Konzerte des zur"+ue+"ckliegenden " +
	"Jahres als Ausbelichtung auf hochwertigem Fotopapier bestellen. Bitte geben Sie hierzu die Zahl der gew"+ue+"nschten " +
	"Exemplare ein. Jeder Klick in das Bestellfeld erh"+oe+"ht die Anzahl, eine manuelle Korrektur ist jederzeit " +
	"m"+oe+"glich. Klicken Sie auf ein Kalenderblatt, um es in einer h"+oe+"heren Aufl"+oe+"sung zu betrachten.</p>\n" +
	"<p>Mit Ihrer Bilderbestellung unterst"+ue+"tzen Sie die F"+oe+"rderprojekte des Vereins „Kulturscheune Schnaittach e.&thinsp;V.“. " +
	"Den <a href=\"#Uebersicht\">Gesamtpreis Ihrer Bestellung</a>, den darin enthaltenen F"+oe+"rderbetrag sowie " +
	"<a href=\"#Zahlweise\">Hinweise zur Zahlweise</a> finden Sie am Ende des Formulars.</p>\n";
var calendarTableStart =
	"<table width=\"100%\">\n";
var calendarTableRowStart =
	"<tr>\n";
var calendarSelection =
	"<td class=\"form-field\" style=\"padding-left: ${padding}\">" +
	"<input name=\"${fieldname}\" type=\"text\" size=\"2\" style=\"text-align: right\" " +
	"onclick=\"calendarUpdateQuantitiesAndPrice( this, 1 )\" onchange=\"calendarUpdateQuantitiesAndPrice( this )\">" +
	"&nbsp;&nbsp;${image}</td>\n";
var calendarImageStyle = 
	" style=\"vertical-align: top\" ";
var calendarEmptyCell =
	"<td>&nbsp;</td>";
var calendarTableRowEnd =
	"</tr>\n";
var calendarTableEnd =
	"</table>\n";
var calendarPaperFormats = // value: format; basePrice; itemPrice; donation; postage
    {
        Start:  "<p style=\"margin-top: 4ex\"><span style=\"display: inline-block; width: 15em\"><a name=\"Uebersicht\">Papierformat:</a></span>" +
	            "<select name=\"Papierformat\" onchange=\"calendarUpdateQuantitiesAndPrice( this )\">\n",
	    Q20:    "<option value=\"20x20 Hochglanz;           2.00; 24.95; 3.00; 3.00\" selected=\"\">20&thinsp;&times&thinsp;20 Hochglanz</option>\n",
	    A4:     "<option value=\"A4 Hochglanz;              2.00; 34.95; 4.00; 3.00\">A4 Hochglanz</option>\n",
	    A4L:    "<option value=\"A4 Hochglanz (Querformat); 2.00; 34.95; 4.00; 3.00\">A4 Hochglanz (Querformat)</option>\n",
	    A4P:    "<option value=\"A4 Hochglanz (Hochformat); 2.00; 34.95; 4.00; 3.00\">A4 Hochglanz (Hochformat)</option>\n",
	    A3:     "<option value=\"A3 Hochglanz;              2.00; 44.95; 5.00; 5.00\">A3 Hochglanz</option>\n",
	    A3L:    "<option value=\"A3 Hochglanz (Querformat); 2.00; 44.95; 5.00; 5.00\">A3 Hochglanz (Querformat)</option>\n",
	    A3P:    "<option value=\"A3 Hochglanz (Hochformat); 2.00; 44.95; 5.00; 5.00\">A3 Hochglanz (Hochformat)</option>\n",
	    End:    "</select></p>\n",
	    Default:{ Q20: false, A4: true, A3: false }
	};
var calendarPaymentChoice =
	"<p><span style=\"display: inline-block; width: 15em\"><a href=\"#Zahlweise\">Zahlweise</a>:</span>" +
	"<select name=\"Zahlweise\" onchange=\"calendarUpdateQuantitiesAndPrice( this )\">\n" +
	"<option value=\"Vorkasse;  0.00\" selected=\"\">Vorkasse</option>\n" +
	"<option value=\"Nachnahme; 4.00\">Nachnahme</option>\n" +
	"</select></p>\n";
var calendarOrderSummary = 
	"<p><span style=\"display: inline-block; width: 15em\">Bestellte Kalender:</span><span id=\"pieces\"></span></p>\n" +
	"<p><span style=\"display: inline-block; width: 15em\">Auftragspauschale:</span><span id=\"charge\"></span><br>\n" +
	"<span style=\"display: inline-block; width: 15em\">Preis f"+ue+"r Kalender:</span><span id=\"price\"></span><br>\n" +
	"<span style=\"display: inline-block; width: 15em\">Porto und Versand:</span><span id=\"postage\"></span><br>\n" +
	"<span style=\"display: inline-block; width: 15em\">Gesamtpreis:</span><span id=\"total\"></span></p>\n<p>" +
	"<span style=\"display: inline-block; width: 15em\">Enthaltener F"+oe+"rderbetrag:</span><span id=\"charity\"></span><br>\n" +
	"Alle Preisangaben inkl. MwSt.</p>\n" +
	"<input type=\"hidden\" name=\"Einzelbilder\" value=\"\">\n" +
	"<input type=\"hidden\" name=\"Abzuege\" value=\"\">\n" +
	"<input type=\"hidden\" name=\"Grundpreis\" value=\"\">\n" +
	"<input type=\"hidden\" name=\"Kalenderpreis\" value=\"\">\n" +
	"<input type=\"hidden\" name=\"Foerderbetrag\" value=\"\">\n" +
	"<input type=\"hidden\" name=\"Versand\" value=\"\">\n" +
	"<input type=\"hidden\" name=\"Gesamtpreis\" value=\"\">\n";
var calendarAdditionalComments =
	"<p class=\"form-field\"><strong>Erg"+ae+"nzende Angaben:</strong><br>\n" +
	"<textarea name=\"Anmerkungen\" cols=\"60\" rows=\"6\"></textarea></p>";
var calendarCheckFailureMessage =
    "Fehler bei der "+Ue+"berpr"+ue+"fung des Feldinhaltes. Bitte senden Sie eine kurze Fehlermeldung an <" + 
    calendarOrderEmail + "> unter Nennung des Formularfeldes, Ihrer Eingabe und des verwendeten Web-Browsers.";
var calendarDeliveryAddress = 
	"<p class=\"form-field\"><strong>Ihr vollst"+ae+"ndiger Name:</strong><br>\n" +
	"<input name=\"realname\" type=\"text\" size=\"60\" onchange=\"return calendarCheckPattern( this, calendarRealnamePattern, calendarRealnameMessage )\"></p>\n" +
	"<p class=\"form-field\"><strong>Stra"+sz+"e und Hausnummer:</strong><br>\n" +
	"<input name=\"Strasse\" type=\"text\" size=\"60\" onchange=\"return calendarCheckPattern( this, calendarStreetPattern, calendarStreetMessage )\"></p>\n" +
	"<p class=\"form-field\"><strong>Postleitzahl und Ort:</strong><br>\n" +
	"<input name=\"Ort\" type=\"text\" size=\"60\" onchange=\"return calendarCheckPattern( this, calendarTownPattern, calendarTownMessage )\"></p>\n" +
	"<p class=\"form-field\"><strong>Land (Lieferung nur innerhalb Mitteleuropas):</strong><br>\n" +
	"<input name=\"Land\" type=\"text\" size=\"60\" value=\"Deutschland\" onchange=\"return calendarCheckPattern( this, calendarCountryPattern, calendarCountryMessage )\"></p>\n" +
	"<p class=\"form-field\"><strong>E-Mail-Adresse:</strong><br>\n" +
	"<input id=\"" + calendarReferenceFieldId + "\" name=\"email\" type=\"text\" size=\"60\" onchange=\"return calendarCheckPattern( this, calendarEmailPattern, calendarEmailMessage )\"></p>\n";
var calendarInvalidDataMessage =
	"Ung"+ue+"ltige Eingabe; bitte korrigieren Sie die rot unterlegten Eingabefelder.\n\n" +
	"Wenn Sie mit der Maus "+ue+"ber ein ung"+ue+"ltiges Eingabefeld fahren, erhalten Sie einen " +
	"Hinweis zum Fehler und zur notwendigen Korrektur.";
var calendarImageSelectionMessage = 
	"Sie haben noch nicht festgelegt, wie viele Kalender Sie bestellen m"+oe+"chten. Bitte geben Sie " +
	"die gew"+ue+"nschte Zahl von Exemplaren ein.";
var calendarRealnamePattern = 
	"^\\S+\\s+\\S.+$";
var calendarRealnameMessage = 
	"Ung"+ue+"ltiger Name; bitte geben Sie Ihren Namen als \"Vorname(n) Nachname\" ein.";
var calendarStreetPattern = 
	"^\\S.+\\s\\d.+$";
var calendarStreetMessage = 
	"Ung"+ue+"ltige Stra"+sz+"e oder Hausnummer; bitte geben Sie Ihre Anschrift als \"Stra"+sz+"e Hausnummer\" ein.";
var calendarTownPattern = 
	"^\\d{5}\\s+\\S.+$";
var calendarTownMessage = 
	"Ung"+ue+"ltige Postleitzahl oder ung"+ue+"ltiger Wohnort; bitte geben Sie Ihre Anschrift als \"PLZ Wohnort\" " + 
	"mit vier- bzw. f"+ue+"nfstelliger Postleitzahl ein.";
var calendarCountryPattern = 
	"^\\S{3}";
var calendarCountryMessage = 
	"Ung"+ue+"ltiger Landesname; bitte geben Sie das Zustellungsland f"+ue+"r Ihre Anschrift ohne Abk"+ue+"rzung ein.";
var calendarEmailPattern =
	"^\\S+@(\\S{2,}\\.)+\\S{2,}$";
var calendarEmailMessage =
	"Ung"+ue+"ltige E-Mail-Adresse; bitte geben Sie Ihre E-Mail-Adresse als \"name@domain.tld\" ein, wobei die " +
	"jede Domain sowie die Top-Level Domain (TLD) aus mindestens zwei Zeichen bestehen muss.";
var calendarFormSubmission =
	"<p class=\"form-text\"><input type=\"submit\" name=\"submit\" value=\"Bestellung abschicken\" onclick=\"return calendarCheckForm( this.form )\">\n" +
	"<input type=\"reset\" name=\"reset\" value=\"L"+oe+"schen\" onclick=\"calendarResetQuantitiesAndPrice( this )\"></p>\n" +
	"<input type=\"hidden\" name=\"recipient\" value=\"${email}\">\n" +
	"<input type=\"hidden\" name=\"sort\" value=\"order:${fieldlist},Papierformat,Zahlweise,Einzelbilder,Abzuege," +
	"Grundpreis,Kalenderpreis,Foerderbetrag,Versand,Gesamtpreis,Anmerkungen,realname,Strasse,Ort,Land,email\">\n" +
	"<input type=\"hidden\" name=\"subject\" value=\"${subject}\">\n" +
	"<input type=\"hidden\" name=\"redirect\" value=\"/orderform-ok.htm\">\n";
var calendarServiceProvider =
	"<div style=\"height: 5px; margin-top: 3ex; background-image: url( separator.gif ); background-repeat: repeat-x\"></div>\n" +
	"<p style=\"margin-top: 3ex\">Dieser Bestellservice ist keine Leistung des Vereins „Kulturscheune Schnaittach e.&thinsp;V.“ " +
	"bzw. der Simmelsdorfer M"+ue+"hle und erfolgt auch nicht in deren Auftrag bzw. auf deren Rechnung. Das Bestellformular " +
	"ist lediglich auf der Website der Simmelsdorfer M"+ue+"hle hinterlegt, um den Bestellvorgang f"+ue+"r Sie so " +
	"einfach wie m"+oe+"glich zu gestalten. Ihre Kalender erhalten Sie direkt vom akkreditierten Fotografen " +
	"der Simmelsdorfer M"+ue+"hle:</p>\n" +
	"<p style=\"padding-left: 4em\">Stefan Hofmann<br>\n" +
	"Johannisgasse 13<br>\n" +
	"91220 Schnaittach<br><br>\n" +
	"<span style=\"display: inline-block; width: 5em\">Telefon:</span>(09153) 997928<br>\n" +
	"<span style=\"display: inline-block; width: 5em\">E-Mail:</span><a href=\"javascript: " +
	"OpenMailForm( 'fotograf', 'Anfrage zur Bilderbestellung' )\">fotograf<span>@</span>die-simmelsdorfer-muehle<span>.</span>de</a></p>";
var calendarAdvancePayment =
	"<p>Bei <a name=\"Zahlweise\">Zahlung per Vorkasse</a> <a href=\"#\" onclick=\"window.print()\">drucken Sie dieses Formular</a> " +
	"bitte vor Absenden der Bestellung aus und "+ue+"berweisen Sie den errechneten Gesamtpreis auf folgendes Konto:</p>\n" +
	"<p style=\"padding-left: 4em\">Stefan Hofmann<br>\n" +
	"<span style=\"display: inline-block; width: 20em\">Sparkasse N"+ue+"rnberg, BLZ 760 501 01</span>BIC/SWIFT-Code: SSKNDE77XXX<br>\n" +
	"<span style=\"display: inline-block; width: 20em\">" + DescrambleString( "27D1A8DBCF7000EE71251DEFBA70A7CA10250DCF1A", 0x93 ) + 
	"</span>" + DescrambleString( "07035A789A70A09DF0A44CEF5A71B7CA80245D9E3A21974AD024CDDF6A51", 0x93 ) + "</p>";
var calendarDeliveryConditions =
	"<p>Die Lieferung bestellter Kalender erfolgt ab Mitte Dezember, fr"+ue+"hestens jedoch 1&ndash;2 Wochen nach Bestellung " +
	"bzw. bei Vorkasse nach Eingang der Zahlung. R"+ue+"ckgabe oder Umtausch von Fotokalendern sind ausgeschlossen, sofern " +
	"die Ware nicht schadhaft ist.</p>\n";



// Calendar Orderform 1.6.0, Copyright (c) 2009-2011, Stefan Hofmann

// This script transforms a form containing a calendar cover for visual display into 
// a form with which copies of the calendar can be selected and ordered by e-mail. The 
// form starts with a brief usage note, followed by the orderable items. Beneath
// the orderable items, the copies' format and their delivery option can be chosen.
// Next, the number of selected photos, the total number of copies, their unit price 
// and the total price are shown. Then follow the fields to enter the name of the
// recipient and the delivery address plus the recipient's e-mail address. The form
// ends with some administrative information about the supplier, the advance-payment
// instructions, and the time until delivery.

// The visually displayed images must be contained within a form tag which already
// provides all necessary data to submit the filled form to the web server. In
// particular, the form tag must comprise the destination URL and submission method 
// as well as other data required by the hoster's offered form-submission interface.
// Images whose extension starts with a double dot are ignored.

// The form must have the ID 'orderform'. Its fields are derived from the images' 
// filenames, replacing intermingled punctuation characters by underscores. Each 
// image may be embraced by an '<a>' tag, which provides a link to a version with 
// a higher resolution. The '<a>' tag is modified such that clicked photos open in
// a new window.

// The available paper format can be specified by an optional array containing the
// property identifiers of the calendarPaperFormats object. If unspecified, a default
// selector for "Q20" and "A4" (default choice) will be created.


function CreateCalendarOrderForm( form, paperFormats )
{
	var html;
	var link;
	var href;
	var next;
	var formId = form.id;
	var content = document.getElementById( "content" );
	var formWidth = content.clientWidth;
	var newHtml = "";
	var busy = true;
	var start = 0;
	var end = 0;
	var width = 0;
	var i = 0;
	
	
	// transform all image links not pertaining to a slide show to open in a new window
	html = form.innerHTML;
	while( busy )
	{
		// try matching a link tag enclosing an image tag
		start = html.search( /<a /i );
		end = html.search( /<\/a>/i );
		if( start >= 0 && end >= 0 && start < end )
		{
			link = html.substring( start, end + 4 );
			if( link.search( /<img /i ) >= 0 )
			{
				// image within link, so modify the link to open in a new window
				next = link.search( />/ ) + 1;
				href = link.substring( 0, next );
				href = href.replace( /\s*target=("[^"">]*"|[^\s>]*)([\s>])/, "$2" );
				if( href.search( /javascript:/i ) < 0 )
				{
				    // open enlarged image in a new window only in case of a regular link
    				href = href.replace( />/, " target=\"_blank\">" );
    			}
				newHtml += html.substring( 0, start ) + href + link.substring( next, end + 4 );
				html = html.substring( end + 4 );
			}
			else
			{
				// no image within link, so skip the link
				newHtml += html.substring( 0, end + 4 );
				html = html.substring( end + 4 );
			}
		}
		else
		{
			// stop parsing if no more image tags
			newHtml += html;
			busy = false;
		}
	}
	form.innerHTML = newHtml;
	
	var headings = document.getElementsByTagName( "h1" );
	var paragraphs = document.getElementsByTagName( "p" );
	var images = new Array();
	var fields = new Array();
	var fieldname = undefined;
	var matches = undefined;
	var choice = undefined;
	var subject = undefined;

	// collect images contained inside the form
	form = document.getElementById( formId );
	html = form.innerHTML;
	busy = true;
	while( busy )
	{
		// try matching a link tag enclosing an image tag
		start = html.search( /<a /i );
		end = html.search( /<\/a>/i );
		if( start < 0 || end < 0 || start >= end )
		{
			// otherwise, try matching a pure image tag
			start = html.search( /<img /i );
			end = html.substring( start + 1 ).search( />/ );
		}		
		if( start >= 0 && end >= 0 && start < end )
		{
			// store found (linked) image tag, but skip those with double-dot extension
			var image = html.substring( start, end + 4 ).replace( /\n/g, "" );
			html = html.substring( end + 4 );
			if( image.search( /src=[^>]*[^.]\.(tif|jpg|png|gif)/i ) >= 0 )
			{
			    // replace slide-show function call with original link, which is stored in 
			    // a specially formatted name tag; currently disabled
			    if( false && image.search( /name="''/ ) >= 0 )
			    {
			        href = image.replace( /^.*\s+name="''([^"''"]*)''".*$/i, "$1" );
			        image = image.replace( /(\s+href)="[^""]*"/i, "$1=\"" + href + "\"" );
			    }
    			images.push( image );
    		}
		}
		else
		{
			// stop parsing if no more image tags
			busy = false;
		}
	}
	
	// do not create an orderform if no orderable items found
	if( images.length < 1 )
	{
	    return( false );
	}
	
	// create order form from collected image tags
	html = calendarUsageNotes + calendarTableStart;
	for( i = 0; i < images.length; i++ )
	{
		// retrieve image filename
		matches = images[ i ].match( /klein\/([^.]+)\.\w{3}/ );
		fieldname = "Anzahl_" + matches[ 1 ].replace( /-/g, "_" );
		fields.push( fieldname );
		// substitutes placeholders in photo-selection template
		if( width == 0 )
		{
			// first column starts without padding
			choice = calendarSelection.replace( /\$\{padding\}/m, "0px" );
		}
		else
		{
			// subsequent columns have padding to column on the left
			choice = calendarSelection.replace( /\$\{padding\}/m, calendarItemPadding + "px" );
		}
		choice = choice.replace( /\$\{fieldname\}/m, fieldname );
		choice = choice.replace( /\$\{image\}/m, images[ i ] );
		choice = choice.replace( /<img ([^>]*)>/mi, "<img $1" + calendarImageStyle + ">" );
		if( width == 0 )
		{
			// first column of row, which cannot be skipped
			html += calendarTableRowStart;
		}
		html += choice;
		width += calendarItemWidth;
		if( width + calendarItemWidth > formWidth )
		{
			// content pane cannot host another column
			html += calendarTableRowEnd;
			width = 0;
		}
	}
	while( width > 0 )
	{
		// need to append column to fill row
		html += calendarEmptyCell;
		width += calendarItemWidth;
		if( width + calendarItemWidth > formWidth )
		{
			// content pane cannot host another column
			html += calendarTableRowEnd;
			width = 0;
		}
	}
	html += calendarTableEnd;
	
	// determine mail subject
	subject = calendarOrderSubject;
	
	// append format selector
	if( typeof( paperFormats ) == "string" )
    {
        html += paperFormats;
    }
    else
    {
        if( ! paperFormats || typeof( paperFormats ) != "object" )
        {
            paperFormats = calendarPaperFormats[ "Default" ];
        }
        html += calendarPaperFormats[ "Start" ];
        for( var format in paperFormats  )
        {
            var option = calendarPaperFormats[ format ];
            if( paperFormats[ format ] )
            {
                option = option.replace( "<option ", "<option selected=\"\" " );
            }
            html += option.replace( /\s+/g, " " );
        }
        html += calendarPaperFormats[ "End" ];
    }
	
	// append order summary and fields for delivery address
	html += calendarPaymentChoice;
	html += calendarOrderSummary;
	html += calendarDeliveryAddress;
	html += calendarAdditionalComments;
	
	// append other (hidden) fields required for order submission and processing
	fields.sort();
	choice = calendarFormSubmission.replace( /\$\{fieldlist\}/m, fields.join( "," ) );
	choice = choice.replace( /\$\{email\}/m, calendarOrderEmail );
	choice = choice.replace( /\$\{subject\}/m, subject );
	html += choice;
	
	// supplemental data
	html += calendarServiceProvider;
	html += calendarAdvancePayment;
	html += calendarDeliveryConditions;
	
	// replace form with transformed form and initialize
	form.innerHTML = html;
	try
	{
    	var calendarReferenceField = document.getElementById( calendarReferenceFieldId );
    	calendarNormalBackgroundColor = calendarReferenceField.currentStyle.backgroundColor;
    }
    catch( error )
    {
        // ignore
    }
    finally
    {
    	calendarResetQuantitiesAndPrice();
    }
	return( true );
}



// This function resets all calculated values to their defaults and updates the
// related form fields, both the visible and the hidden fields.

function calendarResetQuantitiesAndPrice( button )
{
	var form = document.getElementById( "orderform" );
	var field = undefined;
	var i = 0;
	
	for( i = 0; i < form.elements.length; i++ )
	{
		field = form.elements[ i ];
		field.title = "";
		field.style.background = calendarNormalBackgroundColor;
	}
	calendarFillInQuantitiesAndPrice( 0, 0, 0.00, 0.00, 0.00, 0.00 );
	return;
}



// This function counts the number and chosen copies of the selected photos,
// calculates the prices and fees, and updates the related (visible and hidden)
// form fields.

function calendarUpdateQuantitiesAndPrice( field, count )
{
	var form = document.getElementById( "orderform" );
	var calendarPaymentChoice = form.elements[ "Zahlweise" ];
	var paymentOption = calendarPaymentChoice.options[ calendarPaymentChoice.selectedIndex ].value;
	var paymentData = paymentOption.replace( " ", "" ).split( ";" );
	var cashOnDeliveryFee = paymentData[ 1 ] - 0.00;
	var formatChoice = form.elements[ "Papierformat" ];
	var formatOption = formatChoice.options[ formatChoice.selectedIndex ].value;
	var formatData = formatOption.replace( " ", "" ).split( ";" );
	var charge = 0.00;
	var unitprice = formatData [ 2 ] - 0.00;
	var donation = formatData [ 3 ] - 0.00;
	var postage = 0.00;
	var images = 0;
	var pieces = 0;
	var price = 0.00;
	var charity = 0.00;
	var i = 0;
	
	// reset or increment field if count is given
	if( count > 0 )
	{
		if( field.value > 0 )
		{
			field.value = field.value - 0 + count;
		}
		else
		{
			field.value = count;
		}
		field.select();
	}
	
	// sum up field values and highlight wrong ones
	for( i = 0; i < form.elements.length; i++ )
	{
		field = form.elements[ i ];
		if( field.name.search( /_/ ) >= 0 
		&&  field.name.search( /^(form_type|s_subject|s_name|s_phone|[rs]_email|s_message)$/ ) < 0 )
		{
			if( field.value >= 0 )
			{
				// field contains number
				if( field.value > 0 )
				{
					images++;
					pieces += (field.value - 0);
				}
				field.title = "";
				field.style.background = calendarNormalBackgroundColor;
			}
			else
			{
				// field is not numeric
				field.title = "Ung"+ue+"ltige Anzahl";
				field.style.background = calendarErrorBackgroundColor;
			}
		}
	}
	
	// calculate price and update totals
	if( images > 0 )
	{
    	charge = ( calendarOmitCharge )? 0.00 : formatData[ 1 ] - 0.00;
		charity = donation * pieces;
		price = unitprice * pieces + charity;
		postage = ( calendarOmitDeliveryFee )? 0.00 : formatData[ 4 ] - 0.00 + cashOnDeliveryFee;
	}
	calendarFillInQuantitiesAndPrice( images, pieces, charge, price, charity, postage );
	return;
}



// This function updates both the visible and the hidden form fields with the
// supplied prices and fees.

function calendarFillInQuantitiesAndPrice( images, pieces, charge, price, charity, postage )
{
	var form = document.getElementById( "orderform" );
	var total = charge - 0.00 + price + postage;

	calendarFillInPricingItem( images,
    	form.elements[ "Einzelbilder" ],
        document.getElementById( "images" ) );
	
	calendarFillInPricingItem( pieces,
	    form.elements[ "Abzuege" ],
	    document.getElementById( "pieces" ) );
	
	calendarFillInPricingItem( charge.toFixed( 2 ).replace( ".", calendarDecimalPoint ) + " " + calendarOrderCurrency,
	    form.elements[ "Grundpreis" ],
	    document.getElementById( "charge" ) );
	
	calendarFillInPricingItem( price.toFixed( 2 ).replace( ".", calendarDecimalPoint ) + " " + calendarOrderCurrency,
	    form.elements[ "Kalenderpreis" ],
	    document.getElementById( "price" ) );
	
	calendarFillInPricingItem( charity.toFixed( 2 ).replace( ".", calendarDecimalPoint ) + " " + calendarOrderCurrency,
	    form.elements[ "Foerderbetrag" ],
	    document.getElementById( "charity" ) );
	
	calendarFillInPricingItem( postage.toFixed( 2 ).replace( ".", calendarDecimalPoint ) + " " + calendarOrderCurrency,
	    form.elements[ "Versand" ],
	    document.getElementById( "postage" ) );
	
	calendarFillInPricingItem( total.toFixed( 2 ).replace( ".", calendarDecimalPoint ) + " " + calendarOrderCurrency,
	    form.elements[ "Gesamtpreis" ],
	    document.getElementById( "total" ) );
	
	return;
}



// This function updates both the visible and the hidden form fields of a
// pricing item

function calendarFillInPricingItem( value, record, display )
{
    if( record )
    {
    	record.value = value;
	}
    if( display )
    {
    	display.innerHTML = value;
	}
    return;
}



// This function checks all of the forms input fields for valid values and prompts
// the user to correct invalid entries. The function also prompts the user if no
// photos have been selected, i.e. the order's total has a value of zero.

function calendarCheckForm( form )
{
	var success = true;
	var matches = form.elements[ "Gesamtpreis" ].value.replace( calendarDecimalPoint, "." ).match( /(\d+(\.\d+)?)/ );
	var total = ( matches != null )? matches[ 1 ] : 0;
	
	// check all user input fields
	success &= calendarCheckPattern( form.elements[ "realname" ], calendarRealnamePattern, calendarRealnameMessage );
	success &= calendarCheckPattern( form.elements[ "s_name" ], calendarRealnamePattern, calendarRealnameMessage );
	success &= calendarCheckPattern( form.elements[ "Strasse" ], calendarStreetPattern, calendarStreetMessage );
	success &= calendarCheckPattern( form.elements[ "Ort" ], calendarTownPattern, calendarTownMessage );
	success &= calendarCheckPattern( form.elements[ "Land" ], calendarCountryPattern, calendarCountryMessage );
	success &= calendarCheckPattern( form.elements[ "email" ], calendarEmailPattern, calendarEmailMessage );
	success &= calendarCheckPattern( form.elements[ "s_email" ], calendarEmailPattern, calendarEmailMessage );
	
	// display alert if a user input field contains invalid data
	if( ! success )
	{
		alert( calendarInvalidDataMessage );
		return( false );
	}
	
	// check whether at least one item has been ordered
	if( total <= 0 )
	{
		alert( calendarImageSelectionMessage );
		return( false );
	}
	
	// everything OK, form fields already reset by check functions
	return( true );
}



// This function checks whether a field's value matches a particular pattern. The 
// function marks the field as invalid if the check fails and assigns the supplied 
// message to the field's title. If the check succeeds, the field is unmarked and 
// its title is cleared. When an undefined field is supplied, the function returns
// success to ease the integration with different form mailers.

function calendarCheckPattern( field, pattern, message )
{
    var error;
    var success = true;
    if( field )
    {
        try
        {
            // trim multiple and heading/trailing spaces
            var value = field.value.replace( /\s+/g, " " );
            value = value.replace( /^\s+/, "" );
            value = value.replace( /\s+$/, "" );
        	field.value = value;
        
        	// check pattern against trimmed value
        	var matches = value.match( pattern );
        	if( matches == null || matches.length == 0 )
        	{
        		// field does not match pattern
        		field.title = message;
        		field.style.background = calendarErrorBackgroundColor;
            	success = false;
        	}
        	else
        	{
            	// field value is valid
            	field.title = "";
            	field.style.background = calendarNormalBackgroundColor;
            	success = true;
            }
        }
        catch( error )
        {
            // indicate failure, but do not block form submission
    		field.title = calendarCheckFailureMessage;
    		field.style.background = calendarErrorBackgroundColor;
        }
    }
	return( success );
}



// This function checks whether a field's value is numeric and whether its value
// lies within the supplied interval. The function marks the field as invalid if 
// the check fails and assigns the supplied message to the field's title. If the
// check succeeds, the field is unmarked and its title is cleared.

function calendarCheckNumber( field, lower, upper )
{
	var value = field.value - 0;
	
	if( value == NaN )
	{
		// field is not numeric
		field.title = "Ung"+ue+"ltiger Wert; bitte geben Sie eine Zahl ein";
		field.style.background = calendarErrorBackgroundColor;
		return( false );
	}
	else if( !( lower <= value && value <= upper ) )
	{
		// field value lies outside of interval
		field.title = "Ung"+ue+"ltiger Wert; bitte geben Sie eine Zahl zwischen " + lower + " und " + upper + " ein";
		field.style.background = calendarErrorBackgroundColor;
		return( false );
	}
	
	// field value is valid
	field.title = "";
	field.style.background = calendarNormalBackgroundColor;
	return( true );
}

