var req;
var line;

/*These are the basic arrays with all of the information in them.*/

var composer;
var opera;
var role;
var artist;
var path;


/*These arrays are changed, cleaned up, and sorted depending on what changes take place.*/

var displayComposer;
var displayOpera;
var displayRole;
var displayArtist;


/* There are three states: "1" entire array displayed, "2" part of array displayed, "3" only one element displayed.  These variables are used to redefine the "display..." arrays depending on their values. */

var stateComposer = 1;
var stateOpera = 1;
var stateRole = 1;


/* The following two functions for the most part were obtained from...
"http://www.omnytex.com/articles/xhrstruts/"
These functions are used in getting and using XML or CSV files in JavaScript.  The above mentioned site contains an explanation of how this code works.  I did make some changes to these functions. */

function toggleFlag()
{
	if (flag == "notinquotes")
	{
		flag = "inquotes";
	} else {
		flag = "notinquotes";
	}
}

function retrieveURL(url) {
   try 
   {  
      req = new ActiveXObject('Msxml2.XMLHTTP');  
   }
   catch (e) 
   {
      try 
      {   
          req = new ActiveXObject('Microsoft.XMLHTTP');  
      }
      catch (e2) 
      {
          try
          {  
             req = new XMLHttpRequest(); 
          }
          catch (e3) 
          {  
             req = false;   
          }
      }
   }
   req.onreadystatechange = processStateChange;
   try 
   {
      req.open("GET", url, true);
   }  
   catch (e) 
   {
      alert(e);
   }
   req.send(null);
}

function processStateChange() {
   if (req.readyState == 4) { /* Complete */
      if (req.status == 200) { /* OK response */
         var text = req.responseText;                   


        flag = "notinquotes";
	text = text.split(""); // split the whole string into an array of characters
	for(i=0;i<text.length;i++) {	// i is a single character in the csv file
		if (text[i] == "\"") {
			toggleFlag(); // toggle whether or not we are inside of quotes
		}
		if (text[i] == "," && flag=="inquotes") {
			text[i] = "commacommacomma"; // replace comma with "commacommacomma" so that the lines 
		}
	}
	text = text.join(""); // combine the array back into a string
	text = text.replace(/\"/g,"");

         if(!(text.match(/\r?\n$/))) {
            text = text + "\n";
         }
         line = text.split(/\r?\n/)

         /* ".split" makes sure it reads in as a string.  The "/\r?\n/" splits it at the line breaks.  "/r" is the return character and "/n" is the newline character.  The "?" makes the return character optional.  The "/r" has to come first so it doesn't show up as a empty box character in I.E. */

         createBasicArrays(line); 

      } else {
         alert("Problem: " + req.statusText);
      }
   }
}


/* This function takes the array "line", which contains the different lines from the .CSV file, and breaks each line up into its individual parts (composer, opera, role, artist).  The base arrays that are used as the main source of data in this scripting receive their data in this array. */ 

function createBasicArrays(line) {
   var temp;
   var tempPart;

   composer = new Array(line.length);
   opera = new Array(line.length);
   role = new Array(line.length);
   artist = new Array(line.length);
   path = new Array(line.length);


   /* Breaks the .csv file lines into four basic arrays. */

   for (i=0;i<(line.length - 1);i++) { /* Assigns parts of line to arrays. */
      temp = line[i];                  /* "line[i].split('","')" comes out undefined*/
      temp = temp.replace(/^"/, '');
      temp = temp.replace(/"$/, '');
      tempPart = temp.split(',');

      composer[i] = tempPart[0].replace("commacommacomma",",");
      opera[i] = tempPart[1].replace("commacommacomma",",");
      role[i] = tempPart[2].replace("commacommacomma",",");
      artist[i] = tempPart[3].replace("commacommacomma",",");
      path[i] = tempPart[4].replace("commacommacomma",",");
   }

   setupDisplayArrays(composer, opera, role, artist);
}

function setupDisplayArrays(composer, opera, role, artist) {
   displayComposer = createDisplayArray(composer); 
   displayOpera = createDisplayArray(opera);
   displayRole = createDisplayArray(role); 
   displayArtist = createDisplayArray(artist); 

   populateMenus(displayComposer, displayOpera, displayRole, displayArtist);
   
}


/* This function creates a "Display" array from a base array.  This "Display" array is sorted and doesn't have duplicate values in it.  Most of this function is for removing duplicate values while creating the new array. */

function createDisplayArray (basicArray) {
   var newArray = new Array();
   var same;
   var nextElement = 1;

   newArray[0] = basicArray[0];

   for(i=1;i<basicArray.length;i++) {
      same = 0;

      for(n=i-1;n>=0;n--) {
         if(basicArray[i] == basicArray[n]) {
            same = 1;
         }
      }

      if(same == 0) {
         newArray[nextElement] = basicArray[i];
         nextElement++;
      }
   }

   newArray = newArray.sort();
   return newArray;
}


/* These five "populate..." functions redefine the options in the drop down menus. */

function populateMenus(tempComposer, tempOpera, tempRole, tempArtist) {
   populateComposer(tempComposer); 
   populateOpera(tempOpera); 
   populateRole(tempRole); 
   populateArtist(tempArtist);
}

function populateComposer(disComposer) {
   document.forms['searchOpera'].composers.length = disComposer.length;

   for (i=1;i<(disComposer.length);i++) {
      document.forms['searchOpera'].composers.options[i] = new Option(disComposer[i-1],'new value');
   }
}

function populateOpera(disOpera) {
   document.forms['searchOpera'].operas.length = disOpera.length;

   for (i=1;i<(disOpera.length);i++) {
      document.forms['searchOpera'].operas.options[i] = new Option(disOpera[i-1],'new value');
   }
}

function populateRole(disRole) {
   document.forms['searchOpera'].roles.length = disRole.length;

   for (i=1;i<(disRole.length);i++) {
      document.forms['searchOpera'].roles.options[i] = new Option(disRole[i-1],'new value');
   }
}

function populateArtist(disArtist) {
   document.forms['searchOpera'].artists.length = disArtist.length;

   for (i=1;i<(disArtist.length);i++) {
      document.forms['searchOpera'].artists.options[i] = new Option(disArtist[i-1],'new value');
   }
}


/* The following three functions change the display arrays depending on what selection the site-user makes.  The whole purpose of this is to find a particular artist/singer and visit their page.  For example, if the user makes a selection from the list of composers then the following changes will occur: First, the composer display array will be redefined to contain only the selection they made and an option to return to the full list of composers; Second, the opera, role, and artist arrays will be redefined to contain only information relative to that composer.  To continue the example, if the user then selects one of the operas that was written by the previously selected composer the opera list will be redefined to contain only that opera and an option to display all of the operas.  After the opera array is redefined, the role and artist arrays will be redefined to contain only information reflecting the selected composer and opera.  The user then could select a role from the list causing a redefining of the artist array which would only show artist that preform that role.  An artist could then be selected and the user would then be taken to that artist's page, but the user can select an artist from the list anywhere along the way and be taken to that artist's page.  */

function changeComposer () { 

   /* I'll only provide comments for this function because the next two are very similar. */

   var incomingState = stateComposer;
   var temp = document.getElementById("composers");

   /* Gets the selection from the composer menu. */
   var selection = temp.options[temp.selectedIndex].text;

   if(selection == "Composers") {

      /* Brings back the entire list of composers from the composer base array. */
      displayComposer = createDisplayArray(composer);

      /* Resets the state of the composer menu to show that it is showing all of the composers. */
      stateComposer = 1;
   }

   else {

      /* This sets the state of the composer menu to show that it has a specific selection. */
      stateComposer = 3;
      displayComposer = new Array(2);
      displayComposer[0] = selection;

      if(incomingState == 1 || incomingState == 3) {
         /* The "incomingState == 3" allows for changing the other arrays from whatever selections or lists they contain to lists containing just information relative to the selection in the composer array. */

         stateOpera = 2;
         stateRole = 2;

         displayOpera = redefineArray(selection, composer, opera);
         displayRole = redefineArray(selection, composer, role);
         displayArtist = redefineArray(selection, composer, artist);
      }

      if(incomingState == 2) {

         /* The following two "if" statements cause only the menus that don't have a single option selected to be redefined. */

         if(stateOpera != 3) {
            stateOpera = 2;
            var selection2 = displayRole[0];
            displayOpera = redefineArray2(selection, selection2, composer, role, opera);
            displayArtist = redefineArray2(selection, selection2, composer, role, artist);
         }

         if(stateRole != 3) {
            stateRole = 2;
            var selection2 = displayOpera[0];
            displayRole = redefineArray2(selection, selection2, composer, opera, role);
            displayArtist = redefineArray2(selection, selection2, composer, opera, artist);
         }
      }


      displayOpera = createDisplayArray(displayOpera);
      displayRole = createDisplayArray(displayRole);
      displayArtist = createDisplayArray(displayArtist);
   }

   populateMenus(displayComposer, displayOpera, displayRole, displayArtist);
/*   document.forms['searchOpera'].artists.size = displayArtist.length;
UPDATE 12.27.06  - customer doens't want artists to change size, so I've commented out the preceding line. - Stephen Sorensen */


}

function changeOpera () {
   var incomingState = stateOpera;

   var temp = document.getElementById("operas");
   var selection = temp.options[temp.selectedIndex].text;

   if(selection == "Operas/Oratorios") {
      displayOpera = createDisplayArray(opera);
      stateOpera = 1;
   }

   else {

      stateOpera = 3;
      displayOpera = new Array(2);
      displayOpera[0] = selection;

      if(incomingState == 1 || incomingState == 3) {
         stateComposer = 2;
         stateRole = 2;

         displayComposer = redefineArray(selection, opera, composer);
         displayRole = redefineArray(selection, opera, role);
         displayArtist = redefineArray(selection, opera, artist);
      }

      if(incomingState == 2) {
         if(stateComposer != 3) {
            stateComposer = 2;
            var selection2 = displayRole[0];
            displayComposer = redefineArray2(selection, selection2, opera, role, composer);
            displayArtist = redefineArray2(selection, selection2, opera, role, artist);
         }

         if(stateRole != 3) {
            stateRole = 2;
            var selection2 = displayComposer[0];
            displayRole = redefineArray2(selection, selection2, opera, composer, role);
            displayArtist = redefineArray2(selection, selection2, opera, composer, artist);
         }
      }

      displayComposer = createDisplayArray(displayComposer);
      displayRole = createDisplayArray(displayRole);
      displayArtist = createDisplayArray(displayArtist);
   }

   populateMenus(displayComposer, displayOpera, displayRole, displayArtist);
/*   document.forms['searchOpera'].artists.size = displayArtist.length;
UPDATE 12.27.06  - customer doens't want artists to change size, so I've commented out the preceding line. - Stephen Sorensen */
}







function changeRole () {
   var incomingState = stateRole;

   var temp = document.getElementById("roles")
   var selection = temp.options[temp.selectedIndex].text;

   if(selection == "Roles/Fachs") {
      displayRole = createDisplayArray(role);
      stateRole = 1;
   }

   else {

      stateRole = 3;
      displayRole = new Array(2);
      displayRole[0] = selection;

      if(incomingState == 1 || incomingState == 3) {
         stateOpera = 2;
         stateComposer = 2;

         displayOpera = redefineArray(selection, role, opera);
         displayComposer = redefineArray(selection, role, composer);
         displayArtist = redefineArray(selection, role, artist);
      }


      if(incomingState == 2) {
         if(stateOpera != 3) {
            stateOpera = 2;
            var selection2 = displayComposer[0];
            displayOpera = redefineArray2(selection, selection2, role, composer, opera);
            displayArtist = redefineArray2(selection, selection2, role, composer, artist);
         }

         if(stateComposer != 3) {
            stateComposer = 2;
            var selection2 = displayOpera[0];
            displayComposer = redefineArray2(selection, selection2, role, opera, composer);
            displayArtist = redefineArray2(selection, selection2, role, opera, artist);
         }

// the following code was added by Stephen Sorensen 12.28.2006
         if(incomingState== 2 && stateOpera == 3 && stateComposer == 3)
         {
            selection2 = displayOpera[0];
         }
         displayArtist = redefineArray2(selection, selection2, role, opera, artist);
// end of code added


      }

      displayOpera = createDisplayArray(displayOpera);
      displayComposer = createDisplayArray(displayComposer);
      displayArtist = createDisplayArray(displayArtist);
   }

   populateMenus(displayComposer, displayOpera, displayRole, displayArtist);
/*   document.forms['searchOpera'].artists.size = displayArtist.length;
UPDATE 12.27.06  - customer doens't want artists to change size, so I've commented out the preceding line. - Stephen Sorensen */
}








/* This function defines an array depending on the selection from one of the menus.  This function goes through the original base arrays and finds the locations of the selected item then creates an array with the elements that are at the same locations in the other array (e.g. There might be a lot of entries for Mozart in the composer array.  Once it finds all of these, it then looks up all of the operas/works of his in the database.  Then a new array is created containing the different operas/works and is returned from the function. */

function redefineArray(selection, searchedArray, baseArray) {
   var newArray = new Array();
   var counter = 0;

   for(i=0;i<searchedArray.length;i++) {
      if(selection == searchedArray[i]) {
         newArray[counter] = baseArray[i];
         counter++;
      }
   }

   newArray[counter] = "zzz";
   //"zzz" is garbage for the array that will end up as the last element and be removed.

   return newArray;
}


/* This function is similar to the previous function, but it does a search for two separate selections in two separate arrays and only returns elements that are common to both selections.  For example, if the selections are "Mozart" and "Requiem" then the only values returned will be ones that are from Mozart's Requiem, not any of Mozart's other works nor those from someone else's requiem. */

function redefineArray2(selection, selection2, searchedArray, searchedArray2, baseArray) {
   var newArray = new Array();
   counter = 0;

   for(i=0;i<searchedArray.length;i++) {
      if(selection == searchedArray[i]) {
         if(selection2 == searchedArray2[i]) {
            newArray[counter] = baseArray[i];
            counter++;
         }
      }
   }

   newArray[counter] = "zzz";
   //"zzz" is garbage for the array that will end up as the last element and be removed.
   return newArray;
}


/* This function handles selections from the artist menu.  It is comparable to the "change..." functions above in that it redefines the artist array to its complete version upon selection of "All Artists/Singers".  Other then that it takes care of linking to the artist's page upon selection of his or her name.  */

function gotoPage() {

   var temp = document.getElementById("artists")
   var selection = temp.options[temp.selectedIndex].text;

   if(selection == "Artists") {
      displayArtist = createDisplayArray(artist);
      populateArtist(displayArtist);
/*   document.forms['searchOpera'].artists.size = displayArtist.length;
UPDATE 12.27.06  - customer doens't want artists to change size, so I've commented out the preceding line. - Stephen Sorensen */
   }

   else {

      /* The page linked to has to have a file name according to certain standards: be all lower case, have no spaces, and be of type ".html".  Also, the pages for the artists need to be placed in some regular filing/folder pattern, so that this script know where to locate them in the directories. */

   var artistPage = "http://www.rcamweb.com";

   for(i=0;i<=artist.length;i++) {
      if(selection == artist[i]) {
         artistPage = path[i];
         i = artist.length + 1;
      }
   }

   win = window.open(artistPage, "_blank", "toolbar=no, location=no, directories=no," +
                          " status=no, menubar=no, scrollbars=yes, " +
                          "resizable=yes, copyhistory=no, width=800px" +
                          ", height=600px");

// UPDATE 2006.12.27 - scrollbars=no changed to scrollbars=yes by Stephen Sorensen

   win.focus();
   }
}


/*
*/

function resetAll() {
   var temp;
   var catagories = new Array();
   catagories[0] = "composers";
   catagories[1] = "operas";
   catagories[2] = "roles";
   catagories[3] = "artists";

   for(i=0;i<catagories.length;i++) {  
      temp = document.getElementById(catagories[i]);
      temp.selectedIndex = 0;
   }

   changeComposer();
   changeOpera();
   changeRole();
   gotoPage();
}

