var QRStuff = {
  clientLoggedIn: false,
  qrcodeTypeSet: false,
  previewIsDefault: true,
  previewQuery: false,
  requestFields: [], //Output from the validation function
  googleMap: null,
  vCalendarMap: null,
  
  validationDefinitions: {},
  
  init: function(clientLoggedIn)
  {
    this.initValidationDefinitions();
    this.clientLoggedIn = clientLoggedIn;
    Auth.onLoginSucceeded = this.loginSucceeded.bind(this);
    Auth.onFailedLogin = this.loginFailed.bind(this);

    //Use js to set the default date for the vcalendar option based on client local time
    this.updateVCalendarDefaults();
    
    // preview right click detection
    Event.observe( document, 'mousedown', function(e){
      if (e.isRightClick() && e.target.id == 'qrcode-preview')
        this.previewRightClick(e);
    }.bind(this));
    
    this.initUrlHint();
  },
  
  initUrlHint: function() {
    var urlInput=$('qrcode-data-url');
    if(urlInput) {
      urlInput.observe('focus', this.urlHint.bind(this,true));
      urlInput.observe('blur',  this.urlHint.bind(this,false));
    }
  },
  
  urlHint: function(focus,e) {
    var prefix='http://';
    var el=Event.element(e);
    
    if(focus && el.value==prefix) {
      el.value='';
    }
    else if(!focus && el.value=='') {
      el.value=prefix;
    }
  },
  
  initGoogleMapForType: function(type)
  {
    switch(type) {
      case 'MAPS':
        if(this.googleMap==null) {
          this.googleMap = new GoogleMapController(this, 'map', $('google-map'));
        }
        break;
      case 'VCALENDAR':
        if(this.vCalendarMap==null) {
          this.vCalendarMap = new GoogleMapController(this, 'vcalendar-map', $('vcalendar-google-map'));
        }
        break;
    }
  },
  
  loginSucceeded: function()
  {
    this.clientLoggedIn = true;
    if ($('generate-image-button'))
      $('generate-image-button').show();
    
    if ($('generate-image-button-greyed-out'))
      $('generate-image-button-greyed-out').hide();
    
    if ($('batch-link'))
      $('batch-link').show();
    
    if ($('batch-link-greyed-out'))
      $('batch-link-greyed-out').hide(); 
    
    if ($('batch-subscribe-banner'))
      $('batch-subscribe-banner').hide();
    
    if ($('qrcode-type-code'))
    {
      var qrcodeType = $F('qrcode-type-code');
      if (qrcodeType == 'URL' || qrcodeType == 'SOCIAL_NETWORK') {
        if($('qrcode-shorturl-container')) $('qrcode-shorturl-container').show();
      }
    }
    
    if($('qrcode-disclaimer-container-ITUNES_LINK')) $('qrcode-disclaimer-container-ITUNES_LINK').innerHTML='';
    
    this.scheduleRefreshPreview();
  },
  
  loginFailed: function()
  {
  },
  
  onLoad: function(qrcodeType)
  {
    if (!this.qrcodeTypeSet)
      this.setQRCodeType(qrcodeType);
  },
  
  setQRCodeType: function (qrcodeType)
  {
    this.initGoogleMapForType(qrcodeType);
    
    this.qrcodeTypeSet = true;
    
    $('qrcode-info').hide();

    $('qrcode-data-container-TEXT').hide();
    $('qrcode-data-container-URL').hide();
    $('qrcode-data-container-TEL').hide();
    $('qrcode-data-container-SMSTO').hide();
    $('qrcode-data-container-MAILTO').hide();
    $('qrcode-data-container-MATMSG').hide();
    $('qrcode-data-container-VCARD').hide();
    $('qrcode-data-container-MAPS').hide();
    $('qrcode-data-container-WIFI').hide();
    
    $('qrcode-data-container-TWITTER').hide();
    $('qrcode-data-container-FACEBOOK').hide();
    $('qrcode-data-container-LINKEDIN').hide();
    $('qrcode-data-container-FOURSQUARE').hide();
    
    $('qrcode-data-container-PAYPAL_BUY').hide();
    $('qrcode-data-container-VCALENDAR').hide();
    $('qrcode-data-container-ITUNES_LINK').hide();
    $('qrcode-disclaimer-container-ITUNES_LINK').hide();
    $('qrcode-data-container-YOUTUBE').hide();
  
    $('qrcode-shorturl-container').hide();
    
    $('qrcode-data-container-' + qrcodeType).show();
    $('qrcode-type-' + qrcodeType).checked = true;
    
    var disclaimer=$('qrcode-disclaimer-container-' + qrcodeType);
    if(disclaimer) disclaimer.show();
        
    $('qrcode-type-code').value = qrcodeType;  
    
    if (qrcodeType == 'URL' || qrcodeType == 'TWITTER' || qrcodeType == 'FACEBOOK' || qrcodeType == 'LINKEDIN' || qrcodeType == 'FOURSQUARE' || qrcodeType == 'YOUTUBE' || qrcodeType == 'ITUNES_LINK') {
      $('qrcode-shorturl-container').show();
    }
    
    if (qrcodeType == 'TWITTER' || qrcodeType == 'FACEBOOK' || qrcodeType == 'LINKEDIN') {
      this.updateSubtype();
    }
    
    QRStuff.scheduleRefreshPreview();
  },
  
  refreshPreviewTimerEventID: 0,
  scheduleRefreshPreview: function ()
  {
    if (this.refreshPreviewTimerEventID != 0)
      clearTimeout(this.refreshPreviewTimerEventID);
    this.refreshPreviewTimerEventID = this.refreshPreview.bind(this).delay(0.5);
  },
  
  updateVCalendarDefaults: function ()
  {
    if(!$('qrcode-data-vcalendar-start-day')) {
      return;
    }
    var now = new Date();
    $('qrcode-data-vcalendar-start-day').setValue(now.getDate());
    $('qrcode-data-vcalendar-start-month').setValue(now.getMonth());
    $('qrcode-data-vcalendar-start-year').setValue(now.getFullYear());
    $('qrcode-data-vcalendar-end-day').setValue(now.getDate());
    $('qrcode-data-vcalendar-end-month').setValue(now.getMonth());
    $('qrcode-data-vcalendar-end-year').setValue(now.getFullYear());
    
    var timeoffset=now.getTimezoneOffset();
    // -600 -> +1000 , 330 -> -0530
    var timezone = (timeoffset>0 ? '-' : '+') + (timeoffset/60).abs().floor().toPaddedString(2) + (timeoffset%60).toPaddedString(2);
    
    $('qrcode-data-vcalendar-timezone').setValue(timezone);
  },
  
  refreshPreview: function ()
  {
    var typeCode = this.selectedType();
    var subtype = this.selectedSubtype();
    var query = 'type=' + typeCode;
    
    if(!typeCode) {
      return
    }
    
    //Ensure the vcard/mecard state is in sync with the current selection
    if(typeCode=='VCARD') {
      this.updateVcardType()
    }

    var showDefault = false;
    if(!this.validateQRCodeForm()) {
      var showDefault = true;
    }
    
    var shorturl  = $RF('qrcode-shorturl-yes');
    
    if(!showDefault) 
    {
      switch(typeCode)
      {
        case 'TEXT':
          var text = $F('qrcode-data-text');
          query += '&text=' + encodeURIComponent(text);
          break; 
        
        case 'URL':
          var url = $F('qrcode-data-url');
          query += '&url=' + encodeURIComponent(url);
          query += '&shorturl=' + shorturl;
          break;
        
        case 'TEL':
          var tel = $F('qrcode-data-tel-number');
          query += '&tel-number=' + encodeURIComponent(tel);
          break;
        
        case 'SMSTO':
          var number = $F('qrcode-data-smsto-number');
          var message = $F('qrcode-data-smsto-message');
          query += '&smsto-number=' + encodeURIComponent(number);
          query += '&smsto-message=' + encodeURIComponent(message);
          break;
        
        case 'MAILTO':
          var emailAddress = $F('qrcode-data-mailto-email-address');
          query += '&mailto-email-address=' + encodeURIComponent(emailAddress);
          break;
        
        case 'MATMSG':
          var emailAddress = $F('qrcode-data-matmsg-email-address');
          var subject = $F('qrcode-data-matmsg-subject');
          var body = $F('qrcode-data-matmsg-body');
          query += '&matmsg-email-address=' + encodeURIComponent(emailAddress);
          query += '&matmsg-subject=' + encodeURIComponent(subject);
          query += '&matmsg-body=' + encodeURIComponent(body);
          break;
        
        case 'VCARD':
          var firstName = $F('qrcode-data-vcard-first-name');
          var lastName = $F('qrcode-data-vcard-last-name');
          var honorific = $F('qrcode-data-vcard-honorific');
          var rawTelNumber = $F('qrcode-data-vcard-tel-number');
          var telNumber = this.sanitizeTelephoneNumber(rawTelNumber);
          var cellNumber = $F('qrcode-data-vcard-cell-number');
          var faxNumber = $F('qrcode-data-vcard-fax-number');
          var email = $F('qrcode-data-vcard-email');
          var org = $F('qrcode-data-vcard-org');
          var street = $F('qrcode-data-vcard-street');
          var city = $F('qrcode-data-vcard-city');
          var state = $F('qrcode-data-vcard-state');
          var postcode = $F('qrcode-data-vcard-postcode');
          var country = $F('qrcode-data-vcard-country');
          var url = $F('qrcode-data-vcard-url');
          var linkToDownload = $RF('qrcode-data-vcard-link-to-download-yes');        
          query += '&vcard-first-name=' + encodeURIComponent(firstName);
          query += '&vcard-last-name=' + encodeURIComponent(lastName);
          query += '&vcard-honorific=' + encodeURIComponent(honorific);
          query += '&vcard-type=' + encodeURIComponent(subtype);
          query += '&vcard-tel-number=' + encodeURIComponent(telNumber);
          query += '&vcard-cell-number=' + encodeURIComponent(cellNumber);
          query += '&vcard-fax-number=' + encodeURIComponent(faxNumber);
          query += '&vcard-email=' + encodeURIComponent(email);
          query += '&vcard-org=' + encodeURIComponent(org);
          query += '&vcard-street=' + encodeURIComponent(street);
          query += '&vcard-city=' + encodeURIComponent(city);
          query += '&vcard-state=' + encodeURIComponent(state);
          query += '&vcard-postcode=' + encodeURIComponent(postcode);
          query += '&vcard-country=' + encodeURIComponent(country);
          query += '&vcard-url=' + encodeURIComponent(url);
          query += '&vcard-link-to-download=' + linkToDownload;
          break;
        
        case 'MAPS':
          var latitude = $F('qrcode-data-map-latitude');
          var longitude = $F('qrcode-data-map-longitude');
          var type = $F('qrcode-data-map-type');
          query += '&map_latitude=' + latitude; 
          query += '&map_longitude=' + longitude;
          query += '&map_type=' + type;
          query += '&shorturl=1';
          break;
        
        case 'WIFI':
          var ssid = $F('qrcode-data-wifi-ssid');
          var password = $F('qrcode-data-wifi-password');
          var networkType = $F('qrcode-data-wifi-network-type');
          query += '&wifi-ssid=' + encodeURIComponent(ssid);
          query += '&wifi-password=' + encodeURIComponent(password);
          query += '&wifi-network-type=' + encodeURIComponent(networkType);
          break;

        case 'TWITTER':
          if(subtype=='TWITTER') {
            var username=$F('qrcode-data-'+subtype+'-username');
            $('qrcode-data-' + subtype + '-username').removeClassName('error');
            query += '&twitter-subtype=' + subtype;
            query += '&twitter-username=' + encodeURIComponent(username);
            query += '&shorturl=' + shorturl;
          }
          else if(subtype=='TWITTER_STATUS') {
            var tweet = $F('qrcode-data-'+subtype+'-tweet');
            query += '&twitter-subtype=' + subtype;
            query += '&twitterstatus-tweet=' + encodeURIComponent(tweet);
            query += '&shorturl=' + shorturl;
          }
          break;
        
        case 'FACEBOOK':
          var url=$F('qrcode-data-'+subtype+'-url');
          if(subtype=='FACEBOOK') {
            query += '&facebook-subtype=' + subtype;
            query += '&facebook-url=' + encodeURIComponent(url);
            query += '&shorturl=' + shorturl;
          }
          else if(subtype=='FACEBOOK_LIKE') {
            var title = $F('qrcode-data-FACEBOOK_LIKE-title');
            query += '&facebook-subtype=' + subtype;
            query += '&facebooklike-url=' + encodeURIComponent(url);
            query += '&facebooklike-title=' + encodeURIComponent(title);
            query += '&shorturl=' + shorturl;
          }
          break;

        case 'LINKEDIN':
          var url=$F('qrcode-data-'+subtype+'-url');  
          if(subtype=='LINKEDIN') {
            query += '&linkedin-subtype=' + subtype;
            query += '&linkedin-url=' + encodeURIComponent(url);
            query += '&shorturl=' + shorturl;
          }
          else if(subtype=='LINKEDIN_SHARE') {
            query += '&linkedin-subtype=' + subtype;
            query += '&linkedinshare-url=' + encodeURIComponent(url);
            query += '&shorturl=' + shorturl;
          }
          break;
        
        case 'FOURSQUARE':
          var url=$F('qrcode-data-'+typeCode+'-url');
          query += '&foursquare-url=' + encodeURIComponent(url);
          query += '&shorturl=' + shorturl;
          break;
        
        case 'PAYPAL_BUY':
          var paypalAccountEmailAddress = $F('qrcode-data-paypal-buy-account-email-address');
          var itemDescription = $F('qrcode-data-paypal-buy-item-description');
          var itemProductCode = $F('qrcode-data-paypal-buy-item-product-code');
          var itemValue = $F('qrcode-data-paypal-buy-item-value');
          var currencyCode = $F('qrcode-data-paypal-buy-currency-code');
          query += '&paypal-buy-account-email-address=' + encodeURIComponent(paypalAccountEmailAddress);
          query += '&paypal-buy-item-description=' + encodeURIComponent(itemDescription);
          query += '&paypal-buy-item-product-code=' + encodeURIComponent(itemProductCode);
          query += '&paypal-buy-item-value=' + encodeURIComponent(itemValue);
          query += '&paypal-buy-currency-code=' + encodeURIComponent(currencyCode);
          break;
        
        case 'VCALENDAR':
          var eventName = $F('qrcode-data-vcalendar-event-name');
          var startDateTime = this.getDateTimeInput('qrcode-data-vcalendar-start');
          var endDateTime = this.getDateTimeInput('qrcode-data-vcalendar-end');
          var timezone = $F('qrcode-data-vcalendar-timezone');
          var latitude = $F('qrcode-data-vcalendar-map-latitude');
          var longitude = $F('qrcode-data-vcalendar-map-longitude');
          var mapAddress = $F('qrcode-data-vcalendar-map-address');
          query += '&vcalendar-event-name=' + encodeURIComponent(eventName);
          //query += '&vcalendar-event-description=' + encodeURIComponent(eventDescription);
          //query += '&vcalendar-contact-email-address=' + encodeURIComponent(contactEmailAddress);
          query += '&vcalendar-start-date-time=' + encodeURIComponent(startDateTime);
          query += '&vcalendar-end-date-time=' + encodeURIComponent(endDateTime);
          query += '&vcalendar-timezone=' + encodeURIComponent(timezone);
          query += '&vcalendar-map-longitude=' + encodeURIComponent(longitude);
          query += '&vcalendar-map-latitude=' + encodeURIComponent(latitude);
          query += '&vcalendar-map-address=' + encodeURIComponent(mapAddress);
          //query += '&vcalendar-link-to-download=' + linkToDownload;
          break;
      
        case 'ITUNES_LINK':
          var url = $F('qrcode-data-ITUNES_LINK');
          query += '&itunes_link_url=' + encodeURIComponent(url);
          query += '&shorturl=' + shorturl;
          break;
      
        case 'YOUTUBE':
          query += '&youtube-video-id=' + encodeURIComponent($F('qrcode-data-youtube-video-id'));
          query += '&youtube-video-url=' + encodeURIComponent($F('qrcode-data-youtube-video-url'));
          query += '&youtube-type=' + encodeURIComponent($RF('qrcode-data-youtube-type-mobile'));
          query += '&shorturl=' + shorturl;
          break;
      }
    }
    // Add color specifier to query
    query += '&foreground_color=' + $F('qrcode-fgcolor');
    
    if (showDefault)
    {
      $('qrcode-preview').src = '/images/default_qrcode.png';
    }
    else
    {
      var randQuery='r='+Math.floor(Math.random()*1000)+'&'; //Prevent caching - only really needed for shorturls
      $('qrcode-preview').src = 'generate.generate?'+randQuery+'preview=1&' + query;
    }

    this.previewIsDefault = showDefault;
    this.previewQuery = query;
  },
  
  downloadPreview: function()
  {
    if (!this.validateStep1())
      return;
    
    document.location = 'generate.download?' + this.previewQuery;
    
    //Refresh the preview as the shorturl may have changed. Delayed to ensure the get request above has been sent first, as it might chage the shorturl.
    QRStuff.refreshPreview.bind(this).delay(2);
  },
  
  previewRightClick: function(event)
  {
    if (event.shiftKey)
      return;
    
    if (this.previewIsDefault)
    {
      alert("Please enter the required content, and then use the 'Download this image' link to download your QR code.");
    }
    else
    {
      alert("Please use the 'Download this image' link beneath the preview to download your QR code.");
    }
  },
  
  setAveryCode: function(averyCode)
  {
    var averyCodeElement = $('avery-code');
    
    // un-highlight current
    this.highlightAveryCodeSelector(averyCodeElement.value, false);
    
    // highlight selected
    this.highlightAveryCodeSelector(averyCode, true);
    
    // set value to be submitted in form
    averyCodeElement.value = averyCode;
  },

  highlightAveryCodeSelector: function(averyCode, selected)
  {
    if (selected)
      $('avery-code-' + averyCode).addClassName('avery-code-selected');
    else      
      $('avery-code-' + averyCode).removeClassName('avery-code-selected');
  },
  
  validateStep1: function ()
  {
    if(this.validateQRCodeForm()) {
      return true;
    }
    this.missingFieldsAlert(this.requestFields);
    return false
  },
  
  missingFieldsAlert: function(fields) {
    var l = $('validation-alert-fields-list');
    while(l.lastChild) 
    { 
      l.removeChild(l.lastChild); 
    }
    fields.each(function (f) {
      l.appendChild(new Element('li', {}).update(f));
    });
     
    $('validation-alert-box').show();
    this.centerElement($('validation-alert-box'),{});
    $('validation-alert-box-mask').show();
    $('validation-alert-box-mask').setStyle({
      height: document.body.getHeight()+'px'
    });
  },
  
  centerElement: function (el,options) {
    limitX=typeof options.limitX != undefined ? options.limitX : 0;
    limitY=typeof options.limitY != undefined ? options.limitY : 0;
    var elDims = el.getDimensions();
    var viewPort = document.viewport.getDimensions();
    var offsets = document.viewport.getScrollOffsets();
    var centerX = viewPort.width / 2 + offsets.left - elDims.width / 2;
    var centerY = viewPort.height / 2 + offsets.top - elDims.height / 2;
    if ( limitX && centerX < limitX ) {
      centerX = parseInt(limitX);
    }
    if ( limitY && centerY < limitY ) {
      centerY = parseInt(limitY);
    }
    el.setStyle( { position: 'absolute', top: Math.floor(centerY) + 'px', left: Math.floor(centerX) + 'px' });
  },
  
  closeMissingFieldsAlert: function() {
    $('validation-alert-box').hide();
    $('validation-alert-box-mask').hide();
  },

  requireField: function(field, displayName)
  {
    var value = $F(field);
     
    if (value.length > 0 && value != 'http://')
      return true;
      
    alert('Please enter the ' + displayName + '.');
    $(field).focus();
    return false;
  },

  requireMapInput: function()
  {
    if ($F('qrcode-data-map-longitude') != '')
      return true;
      
    alert('Please click a position on the map.');
    return false;
  },
  
  requireOneField: function(fields, display)
  {
    for(var i=0; i<fields.length; ++i)
    {
      if ($F(fields[i]).length > 0)
        return true;
    }    
    
    alert('Please enter the ' + display + '.');
    $(fields[0]).focus();
    return false;
  },

  setMedia: function (media)
  {
    $('qrcode-media').value = media;
  },
  
  widthChanged: function()
  {
    var width = $F('width_pixels_field');
    if (width > 3000)
    {
      $('qrcode-width-info').hide();
      $('qrcode-width-warning').show();
    }
    else
    {
      $('qrcode-width-warning').hide();
      $('qrcode-width-info').show();
    }
  },
  
  setOutputType: function(outputType)
  {
    $('output_type_field').value = outputType;
    
    if (outputType == 'Email')
      $('qrcode-email-fields').show();
    else
      $('qrcode-email-fields').hide();
  },
  
  refreshEmailBodyOnChanges: true,
  refreshEmailBody: function()
  {
    if (!this.refreshEmailBodyOnChanges)
      return;
      
    var senderName = $F('email_sender_name_field');
    var recipientName = $F('email_recipient_name_field');
    
    var body = 'Dear ' + recipientName + '\n'
             + '\n'  
             + 'Attached is a QR Code representing the following content:\n'  
             + '\n'
             + this.qrcodeFormattedData + '\n'
             + '\n'
             + 'Regards\n'
             + senderName + '\n'
             + '\n'  
             + 'This QR Code was generated by www.qrstuff.com';
             
    $('email_body_field').value = body;      
  },
  
  emailBodyChanged: function()
  {
    this.refreshEmailBodyOnChanges = false;
  },
 
 
 /* Used to hide and show the subsections of types that represent multiple subtypes
  * 
  * Replaced setSocialNetwork when social network was split into 4 types 3 of which had subtypes.
  */
  updateSubtype: function() {
    var typeCode = $F('qrcode-type-code');
    firstSubtypeRadio=$('qrcode-data-container-'+typeCode).down('input[type=radio]');
    var subtype=$RF(firstSubtypeRadio);
    
    $('qrcode-data-TWITTER-subtype-TWITTER-info').hide();
    $('qrcode-data-TWITTER-subtype-TWITTER_STATUS-info').hide();
    $('qrcode-data-FACEBOOK-subtype-FACEBOOK-info').hide();
    $('qrcode-data-FACEBOOK-subtype-FACEBOOK_LIKE-info').hide();
    $('qrcode-data-LINKEDIN-subtype-LINKEDIN-info').hide();
    $('qrcode-data-LINKEDIN-subtype-LINKEDIN_SHARE-info').hide();
    
    if(subtype!=null) {
      $('qrcode-data-' + typeCode + '-subtype-' + subtype + '-info').show();
    }
  },
  
  prependHttpIfMissing: function(urlString)
  {
    var pattern=/^https?:\/\//i;
    return pattern.test(urlString) ? urlString : 'http://' + urlString;
  },
  
  validateEmailAddress: function(email) {
    return email.match(/^[^@]+@[^@]+$/);
  },
  
  //Used by send code as email feature
  validateEmailCodeForm: function()
  {
    if (!(QRStuff.requireField('sender_name_field', 'sender name')
      && QRStuff.requireField('sender_email_address_field', 'sender email address')
      && QRStuff.requireField('recipient_name_field', 'recipient name')
      && QRStuff.requireField('recipient_email_address_field', 'recipient email address')
      && QRStuff.requireField('subject_field', 'email subject')
      && QRStuff.requireField('body_field', 'email body')))
     return false;
   
    var senderName = $F('sender_name_field');
    var senderEmailAddress = $F('sender_email_address_field');
    
    if (senderName == senderEmailAddress)
    {
      alert('The sender name and email address should not be the same.');
      return false;
    }
    
    if (!this.validateEmailAddress(senderEmailAddress))
    {
      alert('Please enter a single valid email address of the form user@example.com.');
      return false;
    }
        
        
    var recipientName = $F('recipient_name_field');
    var recipientEmailAddress = $F('recipient_email_address_field');
    
    if (recipientName == recipientEmailAddress)
    {
      alert('The recipient name and email address should not be the same.');
      return false;
    }
    
    if (!this.validateEmailAddress(recipientEmailAddress))
    {
      alert('Please enter a single valid email address of the form user@example.com.');
      return false;
    }
    
    return true;
  },
  
  updateVcardType:function()
  {
    var type = $RF('qrcode-data-vcard-type-vcard');
    
    if (type == 'mecard') 
    {
      $('qrcode-data-vcard-output-type').hide();
      $('qrcode-data-vcard-link-to-download-no').checked = true;
      
      $('qrcode-data-vcard-honorific-container').hide();
      $('qrcode-data-vcard-fax-number-container').hide();
      $('qrcode-data-vcard-cell-number-container').hide();
      
      $$('.required-if-mecard').each(function (el) { el.show(); });
    } 
    else 
    {
      $('qrcode-data-vcard-output-type').show();
      
      $('qrcode-data-vcard-honorific-container').show();
      $('qrcode-data-vcard-fax-number-container').show();
      $('qrcode-data-vcard-cell-number-container').show();
      
      $$('.required-if-mecard').each(function (el) { el.hide(); });
    }
  }, 
  
  getDateTimeInput: function (prefix)
  {
    var day = $F(prefix + '-day');
    var month = $F(prefix + '-month');
    var year = $F(prefix + '-year');
  
    var hour = $F(prefix + '-hour');
    var minute = $F(prefix + '-minute');
    
    return year + '-' + month + '-' + day + 'T' + hour + ':' + minute + ':00';
  },
  
  fixPaypalBuyItemValue: function()
  {
    $('qrcode-data-paypal-buy-item-value').value = 
      this.fixCurrencyAmountString($F('qrcode-data-paypal-buy-item-value'));
  },
  
  fixCurrencyAmountString: function(input)
  {
    var matches = input.match(/([0-9]+(\.[0-9]{2})?)$/);
    
    if (!matches)
      return '';
    
    var s = matches[1];
    
    if (!matches[2])
      s += '.00';
    
    return s;
  },
  
  submitAndRefer: function(referTo)
  {
    if (!this.validateStep1())
      return;
    
    this.setMedia('refer');
    $('qrcode-refer-to').value = referTo;
    $('qrcode-data-form').submit();
  },
  
  sanitizeTelephoneNumber: function(s)
  {
    // same as QRCodeData::sanitizeTelephoneNumber()
    return s.replace(/[^0-9*+]/g, '');
  },
  
  selectedType: function()
  {
    return $F('qrcode-type-code');
  },
  
  selectedSubtype: function()
  {
    var typeCode = this.selectedType();
    switch(typeCode)
    {
      case 'VCARD':
        return $RF('qrcode-data-vcard-type-vcard');
      case 'MAPS':
        return $F('qrcode-data-map-type');
      case 'TWITTER':
      case 'FACEBOOK':
      case 'LINKEDIN':
        firstSubtypeRadio=$('qrcode-data-container-'+typeCode).down('input[type=radio]');
        return $RF(firstSubtypeRadio);
      default:
        return null;
    }
  },
  
  validateQRCodeForm: function() {
    var type = this.selectedType();
    var subType = this.selectedSubtype();
    
    var requestFieldTexts = new Hash();
    var requestFieldNames = new Hash();
    
    if(subType!==null  && typeof this.validationDefinitions[type+':'+subType]!='undefined') {
      var validationDefinition=this.validationDefinitions[type+':'+subType];
    }
    else if(typeof this.validationDefinitions[type]!='undefined') {
      var validationDefinition=this.validationDefinitions[type];
    }
    else {
      if(typeof console!='undefined') {
        console.error('Unknown type '+type);
      }
      return false;
    }
    
    var valid=true;
    
    for(var i=0; i<validationDefinition['rules'].length; i++) {
      var rule=validationDefinition['rules'][i];
      //If the field was already invalid don't apply further tests
      if(requestFieldNames.get(rule.field)) {
        continue;
      }
      if(!this.validateRunRule(rule)) {
        valid=false;
        requestFieldTexts.set(rule.requestText,true); //Set request texts as hash keys so they will be unique.
        requestFieldNames.set(rule.field,true);
      }
    }

    this.requestFields=requestFieldTexts.keys();
    return valid;
  },
  
  validateRunRule: function(rule) {
    var el=$(rule.field);
    var value=el.type=='radio' ? $RF(el) : el.value;
    var valueTrimmed=this.trimString(value);
    
    switch(rule.type) {
      //NB - even text codes can't have a content of just 'http://' per QRCodeData::isValid()
      case 'required':
        if(value=='' || value==null || value=='http://') return false;
        break;
      case 'validate': //Run a custom js rule
        if(!rule.validate(rule.field,value)) return false
        break;
      case 'required_url':
        if(valueTrimmed=='' || valueTrimmed==null || valueTrimmed=='http://') return false;
        break;
      case 'required_phone':
        if(this.sanitizeTelephoneNumber(valueTrimmed)=='' || valueTrimmed==null || valueTrimmed=='http://') return false;
        break;
      case 'required_email':
        if(!this.validateEmailAddress(value)) return false;
        break;
    }
    
    return true;
  },
  
  trimString: function(str) {
    return (str==null) ? null : str.replace(/^\s+|\s+$/, '');
  },
  
  initValidationDefinitions: function() {
    this.validationDefinitions={
      "TEXT": {
        "rules": [
          { "type": "required", "field": "qrcode-data-text", "requestText": "Text content" }
        ]
      },
      "URL": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-url", "requestText": "Website URL" }
        ]
      },
      "TEL": {
        "rules": [
          { "type": "required", "field": "qrcode-data-tel-number", "requestText": "Telephone number" },
          { "type": "required_phone", "field": "qrcode-data-tel-number", "requestText": "A valid Telephone Number"}
        ]
      },
      "SMSTO": {
        "rules": [
          { "type": "required", "field": "qrcode-data-smsto-number", "requestText": "Telephone number" },
          { "type": "required_phone", "field": "qrcode-data-smsto-number", "requestText": "A valid Telephone Number"},
          { "type": "required", "field": "qrcode-data-smsto-message", "requestText": "SMS message contents" }
        ]
      },
      "MAILTO": {
        "rules": [
          { "type": "required", "field": "qrcode-data-mailto-email-address", "requestText": "Email address" },
          { "type": "required_email", "field": "qrcode-data-mailto-email-address", "requestText": "A valid Email address"}
        ]
      },
      "MATMSG": {
        "rules": [
          { "type": "required", "field": "qrcode-data-matmsg-email-address", "requestText": "Email address" },
          { "type": "required_email", "field": "qrcode-data-matmsg-email-address", "requestText": "A valid Email address"},
          { "type": "required", "field": "qrcode-data-matmsg-subject", "requestText": "Email message subject" },
          { "type": "required", "field": "qrcode-data-matmsg-body", "requestText": "Email message contents" }          
        ]
      },
      "VCARD:vcard": {
        "rules": [
          { "type": "required", "field": "qrcode-data-vcard-first-name", "requestText": "First Name" },
          { "type": "required", "field": "qrcode-data-vcard-tel-number", "requestText": "Telephone Number" },
          { "type": "required_phone", "field": "qrcode-data-vcard-tel-number", "requestText": "A valid Telephone Number"}
        ]  
      },
      "VCARD:mecard": {
        "rules": [
          { "type": "required", "field": "qrcode-data-vcard-first-name", "requestText": "First Name" },
          { "type": "required", "field": "qrcode-data-vcard-last-name", "requestText": "Last Name" },
          { "type": "required", "field": "qrcode-data-vcard-tel-number", "requestText": "Telephone Number" },
          { "type": "required_phone", "field": "qrcode-data-vcard-tel-number", "requestText": "A valid Telephone Number"},
          { "type": "required", "field": "qrcode-data-vcard-email", "requestText": "Email address" },
          { "type": "required_email", "field": "qrcode-data-vcard-email", "requestText": "A valid Email address"},
          { "type": "required", "field": "qrcode-data-vcard-street", "requestText": "Street Address" },
          { "type": "required", "field": "qrcode-data-vcard-city", "requestText": "City" },
          { "type": "required", "field": "qrcode-data-vcard-postcode", "requestText": "Zip/Postcode" },
          { "type": "required", "field": "qrcode-data-vcard-country", "requestText": "Country" }
        ]  
      },
      "MAPS": {
        "rules": [
          { "type": "required", "field": "qrcode-data-map-latitude", "requestText": "A valid location" },
          { "type": "required", "field": "qrcode-data-map-longitude", "requestText": "A valid location" }
        ]
      },
      "WIFI": {
        "rules": [
          { "type": "required", "field": "qrcode-data-wifi-ssid", "requestText": "SSID" },
          { "type": "validate", "field": "qrcode-data-wifi-password", "requestText": "Password", "validate":
            function(field,value) { //Don't need a pass for 'No Encryption'
              var networkType=$('qrcode-data-wifi-network-type').value;
              if(networkType=='nopass') return true;
              return value!='';
            }.bind(this)
          }
        ]
      },
      "TWITTER": { //Placeholder for no subtype yet selected
        "rules": [
          { "type": "required", "field": "qrcode-data-TWITTER-subtype-TWITTER", "requestText": "Twitter Profile / Twitter Status Update" }
        ]
      },
      "TWITTER:TWITTER": {
        "rules": [
          { "type": "required", "field": "qrcode-data-TWITTER-username", "requestText": "Twitter user name" }
        ]
      },
      "TWITTER:TWITTER_STATUS": {
        "rules": [
          { "type": "required", "field": "qrcode-data-TWITTER_STATUS-tweet", "requestText": "Twitter message" }
        ]
      },
      "FACEBOOK": { //Placeholder for no subtype yet selected
        "rules": [
          { "type": "required", "field": "qrcode-data-FACEBOOK-subtype-FACEBOOK", "requestText": "Facebook Profile / Facebook Like" }
        ]
      },
      "FACEBOOK:FACEBOOK": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-FACEBOOK-url", "requestText": "Facebook profile URL" }
        ]
      },
      "FACEBOOK:FACEBOOK_LIKE": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-FACEBOOK_LIKE-url", "requestText": "URL of page to be liked" },
          { "type": "required", "field": "qrcode-data-FACEBOOK_LIKE-title", "requestText": "Page title" }
        ]
      },
      "LINKEDIN": { //Placeholder for no subtype yet selected
        "rules": [
          { "type": "required", "field": "qrcode-data-LINKEDIN-subtype-LINKEDIN", "requestText": "LinkedIn Profile / LinkedIn Share" }
        ]
      },
      "LINKEDIN:LINKEDIN": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-LINKEDIN-url", "requestText": "Public profile URL" }
        ]
      },
      "LINKEDIN:LINKEDIN_SHARE": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-LINKEDIN_SHARE-url", "requestText": "URL of page to be shared" }
        ]
      },
      "FOURSQUARE": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-FOURSQUARE-url", "requestText": "FourSquare venue URL" }
        ]
      },
      "PAYPAL_BUY": {
        "rules": [
          { "type": "required", "field": "qrcode-data-paypal-buy-account-email-address", "requestText": "Paypal account email address" },
          { "type": "required_email", "field": "qrcode-data-paypal-buy-account-email-address", "requestText": "Valid paypal account email address"},
          { "type": "required", "field": "qrcode-data-paypal-buy-item-description", "requestText": "Item description" },
          { "type": "required", "field": "qrcode-data-paypal-buy-item-value", "requestText": "Item value" }
        ]
      },
      "VCALENDAR": {
        "rules": [
          { "type": "required", "field": "qrcode-data-vcalendar-event-name", "requestText": "Event name" }
        ]
      },
      "ITUNES_LINK": {
        "rules": [
          { "type": "required_url", "field": "qrcode-data-ITUNES_LINK", "requestText": "iTunes link URL" }
        ]
      },
      "YOUTUBE": {
        "rules": [
          { "type": "validate", "field": "qrcode-data-youtube-video-id", "requestText": "Video ID or video URL", "validate":
            function(field,value) { //Either a valid id or a valid URL are ok. The passed value will be that of the video-id field.
              var trimmedUrl=this.trimString($('qrcode-data-youtube-video-url').value);
              return value!='' || (trimmedUrl!='' && trimmedUrl!='http://');
            }.bind(this)
          }
        ]
      }
    }
  }
  
}

