

/**********************************************************
 *** GLOBAL VARIABLES:                                  ***
 **********************************************************/
var scrollers       = new Array();  // scrolling element stack
var resizers        = new Array();  // resizing element stack
var cycleTimer      = false;        // holds cycleTimer interval
var pauseTimer      = false;        // holds pauseTimer interval
var scrollTimer     = false;        // holds scrollTimer interval
var resizeTimer     = false;        // holds resizeTimer interval
var autoScrollDelay = 15;           // Delay for Auto Scroll (in seconds)
var defaultSpeed    = 10;           // Scroll speed (in pixels)
var scrollSpeed     = defaultSpeed; // Scroll speed (in pixels)
var resizeSpeed     = 3;            // Resize speed (in pixels)
var scrollDistance  = 575;          // Scroll distance (in pixels)
var scrollDirection = "left";       // Scroll direction (left, right, up, down)
var activeTab       = 1;            // current active tab
var nextTab         = 2;            // next tab in the rotation
var totalTabs       = 5;            // Total number of tabs
var userRequest     = false;        // holds a user tab request
var http_request    = false;        // AJAX http_request object


/**********************************************************
 *** EVENT LISTENERS: onload & onscroll                 ***
 *** -------------------------------------------------- ***
 *** Adds an onload and onscroll event listener for the ***
 *** document. Onload event fires the cycling animation ***
 *** of the tabbed sections, whereas onscroll exists to ***
 *** solve a bug in the way Safari renders the page.    ***
 **********************************************************/
// First try DOM methods (Firefox, Opera, etc.)
if (document.addEventListener) {
  window.addEventListener ("load", setCycle, false);
  window.addEventListener ("scroll", updateOnScroll, false);

// Second, try IE proprietary methods
} else if (document.attachEvent) {
  window.attachEvent ("onload", setCycle);
  window.attachEvent ("onscroll", updateOnScroll);

// Otherwise, revert to original methods
} else {
  window.onload = setCycle;
  window.onscroll = updateOnScroll;
} 


/**********************************************************
 *** PRIMARY FUNCTION: setCycle()                       ***
 *** -------------------------------------------------- ***
 *** Starts the automatic cycling of the tabs on a 5    ***
 *** second timer.                                      ***
 **********************************************************/
function setCycle() {

  var curTab = document.getElementById("tab_" + activeTab);
  var curWidth = curTab.getElementsByTagName("h4")[0].innerHTML.length * 10;
  curTab.style.width = "150px";//curWidth + "px";
	
  cycleTimer = setInterval("showTab(nextTab)",(autoScrollDelay * 1000));
  
  // The following code was added to the onload function
  // to fix a display bug in IE7, where the contact form
  // would not always display on the first page load.
  document.getElementById('contactForm').style.display = "none";
  document.getElementById('contactForm').style.display = "block";

} // End: setCycle


/**********************************************************
 *** SECONDARY FUNCTION: updateOnScroll()               ***
 *** -------------------------------------------------- ***
 *** resets the footer position on a scroll event, this ***
 *** is a work-around for Safari since they don't abide ***
 *** the min-height css rule.                           ***
 **********************************************************/
function updateOnScroll() {

  // Set the footer's base to 0px (the bottom of the page)
  document.getElementById('footer').style.bottom = "0px";

} // End: updateOnScroll()


/**********************************************************
 *** PRIMARY FUNCTION: clickTab()                       ***
 *** -------------------------------------------------- ***
 *** Handles timer collisions when a user clicks on a   ***
 *** tab, then fires showTab() or adds the item to the  ***
 *** userRequest variable for later display.            ***
 **********************************************************/
function clickTab(id, title) {
  // If the user clicked on the active tab, do nothing
  if(id == activeTab) { return false; }
  
  clearInterval(cycleTimer); // clear the cycleTimer and
  cycleTimer = false;        // then set cycleTimer to false
  
  // *** the following was commented out to disable the 
  // *** autoscroll feature from resuming after a user
  // *** clicks on a tab. 
  
  // If a pauseTimer already exists, clear it out.
  //if(pauseTimer) {
  //  clearInterval(pauseTimer);
  //}

  // Set the pauseTimer for a 5 second delay
  //pauseTimer = setTimeout(setCycle, 5000);
  
  // *** End
  
  // If there is currently an animation active...
  if(scrollTimer || resizeTimer) {
    userRequest = id;  // hold the tab # for later display
  } else {
    showTab(id);       // otherwise, show the requested tab
  }
} // End: clickTab()


/**********************************************************
 *** PRIMARY FUNCTION: showTab()                        ***
 *** -------------------------------------------------- ***
 *** Sets the active tab, calls the scrolling animation ***
 *** and updates the next tab in the loop.              ***
 **********************************************************/
function showTab(id) {
  // Populate some variables with the old & new tab objects 
  var old_tab     = document.getElementById("tab_" + (activeTab));
  var new_tab     = document.getElementById("tab_" + (id));
  var old_content = document.getElementById("tab_content_" + (activeTab));
  var new_content = document.getElementById("tab_content_" + (id));
  
  // Set the new tab's class to 'active'
  new_tab.setAttribute("class", "active"); 
  new_tab.setAttribute("className", "active");
 	
  // Reset the old tab's class
  old_tab.setAttribute("class", ""); 
  old_tab.setAttribute("className", "");

  // Call the scrolling animation initialization
  resizeIt(old_tab,new_tab);

  // Call the scrolling animation initialization
  scrollIt(old_content,new_content);
  
  // Update the activeTab and nextTab variables
  activeTab = id;
  nextTab = activeTab + 1;
  
  // Basic loop for tabs
  if(nextTab > totalTabs) {
    nextTab = 1;
  }
} // End: showTab()


/**********************************************************
 *** SECONDARY FUNCTION: scrollIt()                     ***
 *** -------------------------------------------------- ***
 *** Adds position properties to the elements and adds  ***
 *** the elements to the stack. Then starts the scroll  ***
 *** function on a 1 millisecond timer.                 ***
 **********************************************************/
function scrollIt(old_el, new_el) {
  var myDir = "";
  var oldTab = old_el.id.substring(12) * 1;
  var newTab = new_el.id.substring(12) * 1;
  
  // Select scrolling direction
  switch(scrollDirection) {
    case "left":
      if(oldTab > newTab) { myDir = "right"; }
      else { myDir = scrollDirection; }
      break;
    case "right":
      if(oldTab > newTab) { myDir = "left"; }
      else { myDir = scrollDirection; }
      break;
    case "up":
      if(oldTab > newTab) { myDir = "down"; }
      else { myDir = scrollDirection; }
      break;
    case "down":
      if(oldTab > newTab) { myDir = "up"; }
      else { myDir = scrollDirection; }
      break;
    default:
      myDir = scrollDirection;
      break;
  }
     
  // Add direction as properties of the objects
  old_el.direction = myDir;
  new_el.direction = myDir;

  // Add start positions as properties of the object
  // These reflect the actual element's (style.left)
  // Note: these should really not be hard-coded
  old_el.pos = 2;
  new_el.pos = scrollDistance;

  // Add the elements to the scroller stack
  scrollers.push(old_el);
  scrollers.push(new_el);

  // If no scrollTimer exists, start one to execute scroll()
  if(!scrollTimer) {
    scrollTimer = setInterval("scroll()", 1);
  }

} // End: scrollIt()


/**********************************************************
 *** TERTIARY FUNCTION: scroll()                        ***
 *** -------------------------------------------------- ***
 *** Displays the elements, processes one step of the   ***
 *** animation, then hides elements no longer in view.  ***
 **********************************************************/
function scroll() {
  // If the new element is not displayed, display it
  if(scrollers[1].style.display == "" || scrollers[1].style.display == 'none') {
    scrollers[1].style.display = 'block';
  }
  
  // Place the elements at the position indicated by their
  // pos property. (We do this first so that new elements
  // start in the right spots.
  switch(scrollers[1].direction) {
    case "left":
      scrollers[0].style.left = scrollers[0].pos + "px";
      scrollers[1].style.left = scrollers[1].pos + "px";
      break;
    case "right":
      scrollers[0].style.left = -1 * scrollers[0].pos + "px";
      scrollers[1].style.left = -1 * scrollers[1].pos + "px";
      break;
    case "up":
      scrollers[0].style.top = scrollers[0].pos + "px";
      scrollers[1].style.top = scrollers[1].pos + "px";
      break;
    case "down":
      scrollers[0].style.top = -1 * scrollers[0].pos + "px";
      scrollers[1].style.top = -1 * scrollers[1].pos + "px";
      break;
  }
  
  // Update the position property of the elements by speed.
  // Subtract for upwards movement, add for downwards.
  scrollers[0].pos -= scrollSpeed;
  scrollers[1].pos -= scrollSpeed;

  // Basic makeshift tweening (slowdown effect)
  for(var i=1; i <= scrollSpeed; i++) {
    var pos_min = Math.floor(scrollDistance / 100) * ((i) * scrollSpeed) - Math.ceil(scrollSpeed / 2);
    var pos_max = Math.floor(scrollDistance / 100) * ((i) * scrollSpeed) + Math.ceil(scrollSpeed / 2);

    if(scrollers[1].pos >= pos_min && scrollers[1].pos <= pos_max) {
      // reduce the speed by one
      if(scrollSpeed > 1) { scrollSpeed--; }
      //alert(scrollers[1].pos);
  	}
  }
  
  // If the new element reaches (or exceeds 2)
  if(scrollers[1].pos <= 2) {
    // Set it to 2 and hide the old element
    scrollers[1].style.left = "2px";
    scrollers[0].style.display = 'none';

    // Clear the scrollTimer and set to false
    clearInterval(scrollTimer);
    scrollTimer = false;
    
    // Remove the elements from the scrollers stack
    scrollers = [];
    
    // reset the scrollSpeed
    scrollSpeed = defaultSpeed;
    
    // Check for, and execute any waiting user requests
    if(userRequest && !resizeTimer) {
      showTab(userRequest);
      userRequest = false;
    }
  }
} // End: scroll()


/**********************************************************
 *** SECONDARY FUNCTION: resizeIt()                     ***
 *** -------------------------------------------------- ***
 *** Adds position properties to the elements and adds  ***
 *** the elements to the stack. Then starts the scroll  ***
 *** function on a 1 millisecond timer.                 ***
 **********************************************************/
function resizeIt(old_el, new_el) {

  // Get the h4 tag within the element
  var oldWidth = old_el.getElementsByTagName("h4")[0].innerHTML.length * 9;
  var newWidth = new_el.getElementsByTagName("h4")[0].innerHTML.length * 9;

  // Add minWidth and maxWidth properties to the tab elements  
  old_el.minWidth = 21;
  old_el.maxWidth = 150;//oldWidth;
  new_el.minWidth = 21;
  new_el.maxWidth = 150;//newWidth;
  
  // Add current width as properties of the object
  old_el.curWidth = old_el.maxWidth;
  new_el.curWidth = new_el.minWidth;

  // Add the elements to the scroller stack
  resizers.push(old_el);
  resizers.push(new_el);

  // If no scrollTimer exists, start one to execute scroll()
  if(!resizeTimer) {
    resizeTimer = setInterval("resize()", 1);
  }
} // End: resizeIt()


/**********************************************************
 *** TERTIARY FUNCTION: resize()                        ***
 *** -------------------------------------------------- ***
 *** Processes one step of the resizing animation.      ***
 **********************************************************/
function resize() {

  // Update the curWidth property of the elements by speed.
  // Subtract for shrinking, add for growing.
  if(resizers[0].curWidth >= resizers[0].minWidth + resizeSpeed) {
    resizers[0].curWidth -= resizeSpeed;
  } else {
    resizers[0].curWidth = resizers[0].minWidth;
  }

  if(resizers[1].curWidth <= resizers[1].maxWidth - resizeSpeed) {
    resizers[1].curWidth += resizeSpeed;
  } else {
    resizers[1].curWidth = resizers[1].maxWidth;
  }
  
  // Set the elements width to the curWidth property.
  resizers[0].style.width = resizers[0].curWidth + "px";
  resizers[1].style.width = resizers[1].curWidth + "px";
  
  // If both elements reach their endpoint
  if(resizers[0].curWidth == resizers[0].minWidth && resizers[1].curWidth == resizers[1].maxWidth) {
  
    // Clear the resizeTimer and set to false
    clearInterval(resizeTimer);
    resizeTimer = false;
    
    // Remove the elements from the scrollers stack
    resizers = [];
    
    // Check for, and execute any waiting user requests
    if(userRequest && !scrollTimer) {
      showTab(userRequest);
      userRequest = false;
    }
  }
} // End: resize()


/**********************************************************
 *** AJAX FUNCTION: makePOSTRequest()                   ***
 *** -------------------------------------------------- ***
 *** Creates an http_request (POST) and sends data to   ***
 *** email.php.                                         ***
 **********************************************************/
function makePOSTRequest(url, parameters) {
  http_request = false; // Reset this just in case
  
  // First check DOM methods (Mozilla, Safari, etc.)
  if (window.XMLHttpRequest && !window.ActiveXObject) { 
    // Create a new XMLHttpRequest object
    http_request = new XMLHttpRequest();

    // Override the type to match the return content type
    if (http_request.overrideMimeType) {
      http_request.overrideMimeType('text/html');
    }
    
  // Second, check for IE's ActiveX
  } else if (window.ActiveXObject) {

    // Try the most recent XMLHTTP ActiveX...
    try { 
        http_request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      // If it fails, try an older XMLHTTP ActiveX...
      try {
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {  }
    }
  }
  
  // If no http_request can be created, alert the user.
  if (!http_request) {
    showNotification("invalid", "There was an error submitting your request, your browser does not support this method.");
    return false;
  }

  // Set up the response handler and configure the request.
  http_request.onreadystatechange = handleResponse;
  http_request.open('POST', url, true);
  http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  http_request.setRequestHeader("Content-length", parameters.length);
  http_request.setRequestHeader("Connection", "close");
  
  // Send the Request.
  http_request.send(parameters);
  
} // End: makePOSTRequest()


/**********************************************************
 *** SECONDARY FUNCTION: handleResponse()               ***
 *** -------------------------------------------------- ***
 *** Handles the response codes (or lack thereof) of    ***
 *** the http_request.                                  ***
 **********************************************************/
function handleResponse() {
  // If we get a response from the server...
  if (http_request.readyState == 4) {
  
    // Check the server response is 200 (everything ok)
    // and see if we got "true" from the script...
    if (http_request.status == 200 && http_request.responseText == "true") {
    
      // Show the thank you notification
      showNotification("thankyou");            
    
    } else {
      // Otherwise, show a default error
      showNotification("error");            
    }
  }
} // End: handleResponse()


/**********************************************************
 *** PRIMARY FUNCTION: sendMessage()                    ***
 *** -------------------------------------------------- ***
 *** Calls form validation, then assembles the POST     ***
 *** string and starts the http_request.                ***
 **********************************************************/
function sendMessage(contactForm) {

  // If the form validates ok...
  if(validateForm(contactForm)) {
  
    // Build the POST string
    var poststr = "name=" + encodeURI(document.getElementById("name").value) +
                  "&email=" + encodeURI( document.getElementById("email").value ) +
                  "&phone=" + encodeURI( document.getElementById("phone").value ) + 
                  "&message=" + encodeURI( document.getElementById("message").value );
    
    // Then make the POST request
    makePOSTRequest('scripts/email.php', poststr);
    return false;
  } else {
  	return false;
  }
} // End: sendMessage()


/**********************************************************
 *** PRIMARY FUNCTION: showNotification()               ***
 *** -------------------------------------------------- ***
 *** Shows a notifaction (error, thank you, etc.) to    ***
 *** the user.                                          ***
 **********************************************************/
function showNotification(type, message) {
  
  // Set a default value for message
  message = (typeof message == "undefined") ? "" : message;

  // Set up some object variables for the notification divs
  not_div_bg = document.getElementById("notification_bg");
  not_div    = document.getElementById("notification");
  
  // Select the proper response based on the notification type
  switch(type) {
    case "thankyou":
      var user_name = document.getElementById("name").value
      message += "Thank you, " + user_name + ". Your message has been sent.";
      
      // Clear the message field on a successful send
      document.getElementById('message').value = "";
      break;
    case "error":
      message += "An error occurred while sending your message. Please try again in a few minutes.";
      break;
    case "invalid":
      if(message == "") {
        message += "Please complete all form fields to send your message.";
      }
      break;
    default:
      break;
  }
  
  // If we get a "close" type, hide the notification divs
  if(type == "close") {
    not_div_bg.style.display = 'none';
    not_div.style.display = 'none';

    // Fixes an IE7 bug where the form would otherwise disappear
    // after displaying the notification...
    document.getElementById('contactForm').style.display = 'block';
    
  // Otherwise, create the html output and display the notification
  } else {
    var html  = "<p>" + message + "</p>";
        html += "<img src='images/ui/button-close.png' alt='Close' onclick='showNotification(\"close\");' />";
    
    not_div.innerHTML = html;
    
    not_div_bg.style.display = 'block';
    not_div.style.display = 'block';
    
    // Fixes an IE7 bug where the form would otherwise disappear
    // after displaying the notification...
    document.getElementById('contactForm').style.display = 'none';
  }
} // End: showNotification()


/**********************************************************
 *** FORM VALIDATION FUNCTION: validateForm()           ***
 *** -------------------------------------------------- ***
 *** Calls individual validations for form fields.      ***
 **********************************************************/
function validateForm(thisform) {
  // Set object variables for the form fields
  var fm_name    = document.getElementById('name');
  var fm_email   = document.getElementById('email');
  var fm_message = document.getElementById('message');

  // Call "Required" validation for Name field
  if(validateRequired(fm_name) == false) {
    showNotification("invalid", "Please enter your name to send a message or an inquiry.");
    return false;
  }

  // Call "Text Only" validation for Name field
  if(validateTextOnly(fm_name) == false) {
    showNotification("invalid", "The name field may only contain the letters A through Z and spaces.");
    return false;
  }

  // Call "Required" validation for Email field
  if(validateRequired(fm_email) == false) {
    showNotification("invalid", "Please enter an e-mail address to send a message or an inquiry.");
    return false;
  }

  // Call "Email" validation for Email field
  if(validateEmail(fm_email) == false) {
    showNotification("invalid", "Your e-mail address appears to be invalid.");
    return false;
  }

  // Call "Required" validation for Message field
  if(validateRequired(fm_message) == false) {
    showNotification("invalid", "Please enter a message to be sent.");
    return false;
  }
  
  // If everything checks out, return true
  return true;

} // End: validateForm()


/**********************************************************
 *** FORM VALIDATION FUNCTION: validateRequired()       ***
 *** -------------------------------------------------- ***
 *** Checks for empty input fields.                     ***
 **********************************************************/
function validateRequired(field) {
  if (field.value == null || field.value == "") {
    return false;
   } else {
    return true;
  }
}

/**********************************************************
 *** FORM VALIDATION FUNCTION: validateTextOnly()       ***
 *** -------------------------------------------------- ***
 *** Checks for non Alpha characters (allows spaces).   ***
 **********************************************************/
function validateTextOnly(field) {
  if(field.value.search(/[^a-zA-Z\s]/) == -1) {
    return true;
  } else {
    return false;
  }
}

/**********************************************************
 *** FORM VALIDATION FUNCTION: validateEmail()          ***
 *** -------------------------------------------------- ***
 *** Checks for properly forms email addresses x@y.c.   ***
 **********************************************************/
function validateEmail(field) {
  var apos   = field.value.indexOf("@");
  var dotpos = field.value.lastIndexOf(".");
  if (apos < 1 || dotpos - apos < 2) {
    return false;
  } else {
    return true;
  }
}

/**********************************************************
 *** PRIMARY FUNCTION: maskPhone()                      ***
 *** -------------------------------------------------- ***
 *** Sets a common mask for phone numbers.              ***
 **********************************************************/
function maskPhone(field) {
  
  // Split the field value into individual characters
  var digits = field.value.split('');

  // In case of international number, exit
  if(digits[0] == "+" || digits.length == 0 || field.value == " ") {
    return true;
  }

  // Remove any character that is not a number
  for(var i = 0; i < digits.length; i++) {
    if(isNaN(digits[i]) || digits[i] == " ") { 
      digits.splice(i,1);
    }
  }

  // Rmove a leading 1 in the case of 11 digits (i.e. - 1(555)555-5555)
  if(digits.length == 11 && digits[0] == 1) {
    digits.splice(0,1);
  }

  // If the phone number is not 10 digits, fail and alert the user
  if(digits.length != 10) {
    showNotification("invalid", "The phone number you entered appears to be invalid.");
    return false;
  }
  
  // Format the actual mask
  var tel = "(";
  for(var i = 0; i < digits.length; i++) {
    if(i == 3) { tel += ') ' }
    if(i == 6) { tel += '-' }
    tel += digits[i];
  }

  // Repopulate the form field.
  field.value = tel;

} // End: maskPhone()
