/*******************************************
 * Nokia Maps site - dynamic functionality *
 *******************************************/

/**
 * Returns hbx.mlc or empty string
 * Used by Flash to access the HBX mlc value
 */
function getHbxMlc() {
  var s = '';
  try {
    return hbx.mlc;
  }catch(e) {
    return s;
  }
}

/**
 * Creates a cookie with specified params
 */
function createCookie(name,value,hours) {
	if (hours) {
		var date = new Date();
		date.setTime(date.getTime()+(hours*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

/**
 * Returns the value of the named cookie, or null if no such cookie is found
 */
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

/**
 * String comparison utility function
 *
 * @params str1, str2 Strings to be compared
 */
function strComp(str1, str2) {
  if ( str1 > str2) return 1;
	if ( str1 < str2) return -1;
	else return 0;
}

/**
 * Device list sort function
 * Puts E-devices first, N-devices next, Numerical devices last
 *
 * @param el1 first element containing the device name text node
 * @param el2 second element containing the device name text node
 */
function deviceSort( el1, el2 ) {
	//get device name from device items in DOM array
	a = $(el1).find('phone_id_txt').text();
	b = $(el2).find('phone_id_txt').text();

	if(a.indexOf("Nokia N") != -1 && b.indexOf("Nokia N") != -1) 
		return -strComp(a, b);
	if(a.indexOf("Nokia E") != -1 && b.indexOf("Nokia E") != -1) 
		return -strComp(a, b);
	if(a.indexOf("Nokia E") != -1 && b.indexOf("Nokia N") != -1) 
		return strComp(a, b);
	if(b.indexOf("Nokia E") != -1 && a.indexOf("Nokia N") != -1) 
		return strComp(a, b);
	return -strComp(a, b);
}


/**
 * Container holding dynamic functionality for Nokia Maps feature pages
 */
var MapsFunctions = {
  //currently active device
  device : '',

  //currently selected Maps version
  version : '',
  //counter used to generate HTML for feature-rows
  featureCount : 0,

	//global field holding the number of the related features 
  //associated with currently viewed feature used at least by
  //showRelatedFeatures and addFeatureHTML
	featuresTotal : -1,
  
	/** 
   * Parse the XML and create the device list 
   *
   * @param context string specifying whether the function is called from
   *                Features main page context or from P&C page
   */
  generateDeviceList : function(context) {
		//sort devices
    //go through all devices
		var deviceArray = [];
		$('devices > item', XMLData.devices).each(function(){
			deviceArray.push($(this));
		});
		deviceArray.sort(deviceSort);

		//gps icons
		//gpsIconYes = $('item#general gps_icon', XMLData.devices).text();
		//gpsIconNo = $('item#general no_gps_icon', XMLData.devices).text();

		//gps texts
		gpsTxtYes = $('general gps_txt', XMLData.devices).text();
		gpsTxtNo = $('general no_gps_txt', XMLData.devices).text();

		$.each(deviceArray, function() {
      // software version code
      var version = $(this).find('maps_version').text();
      var versionText = $('maps_version_names '+version, XMLData.devices).text();
      var versionHTML = '<span class="versionTxt">'+versionText+'</span>';

      // phone image location
      var img = $(this).find('image').text();
			
			gps = $('gps', this).text();
			if(gps == 'true') {
				gpsHTML = '<span class="gpsTxt green">' + gpsTxtYes + '</span>';
				//gpsHTML = '<img class="gpsIcon" src="'+gpsIconYes+'" />'; 
			} else {
				gpsHTML = '<span class="gpsTxt grey">' + gpsTxtNo + '</span>';
				//gpsHTML = '<img class="gpsIcon" src="'+gpsIconNo+'" />'; 
			}
			
			// device name
      var device = $(this).find('phone_id_txt').text();

      var imgHTML = '<img class="phoneImg" src="'+img+'" />';
      var txtHTML = '<span class="captionPhone">'+device+'</span>';
      var deviceHTML = '<div class="phoneContainer">' +
                         '<div class="selectPhone" onclick="MapsFunctions.deviceSelected(\''+device+'\',\''+version+'\',\''+context+'\');">' +
                           imgHTML + txtHTML + gpsHTML + versionHTML +
                         '</div>' +
                       '</div>';
      
      $(deviceHTML).appendTo('#device_selector');

      //Initialize device filter
      //$('#device_filter').val('').keyup(MapsFunctions.filterDevice);
      MapsFunctions.resetFilter();
    });
    
    //device hover effects
    $('.selectPhone').hover(
      function() {
        $(this).addClass('selectPhoneHover');
        $('.captionPhone', this).addClass('captionPhoneHover');
        //$('.gpsTxt', this).addClass('gpsTxtHover');
      },
      function() {
        $(this).removeClass('selectPhoneHover');
        $('.captionPhone', this).removeClass('captionPhoneHover');
        //$('.gpsTxt', this).removeClass('gpsTxtHover');
      }
    );
  },
  
  resetFilter: function() {
     $('#device_filter').val('').keyup(MapsFunctions.filterDevice);
     //this.showDeviceSelector();
     //this.filterDevice();
     $('#device_not_matched').hide();
  },

  /**  
   * Device list mouse-click handler - called when user clicks on any of the devices
   * 
   * @param dev String, device name
   * @param ver String, maps version ('s60_2', 's60_3' or 's40_1')
   * @param context String, 'features' or 'pricing'
   *
   *  - Saves selected device in a cookie
   *  - Calls the context-specific selected device handler:
   *    device specific features, device specific pricing
   */
  deviceSelected : function(dev, ver, context) {
    //set cookies for maps version and maps device
    createCookie('maps_device', dev, 24);
    createCookie('maps_version', ver, 24);
    MapsFunctions.device = dev;
    MapsFunctions.version = ver;
    switch(context) {
      case 'features':
        MapsFunctions.showDeviceFeatures(ver,dev);
        break;
      case 'pricing':
        //Prices and coverage handler
        //"true" allows the redirect to the prices and coverage page for the correct Maps version
        MapsFunctions.setPricingHeading(true);
        break;
    }
  },
  
  /**
   * Toggles a customized heading for the Prices & Coverages pages
   * called by the device selector / parseDeviceXML wrapper
   * 
   * Fetches the locations of Maps 3.0, 2.0 or S40/1.0 pricing pages from the HTML links
   *
   * @param changePage Boolean value indicating whether the user has to be taken to a
   *                   a different page. 
   */
  setPricingHeading : function(changePage) {
    if (MapsFunctions.version === PageVars.mapsVersion && MapsFunctions.device != null ) {
     //Toggle device name in the page heading depending on current device selection 
      MapsFunctions.modifyHtmlHeading('device_heading', headingObj, PageVars.mapsVersion, true);
      MapsFunctions.hideDeviceSelector(true);
      $('#device_selected_head')[0].style.display="block";
      $('#device_selector_head')[0].style.display="none";
    } else {
      if(changePage) {
        /*//check which page should be linked to externally
        if (PageVars.mapsVersion === 's60_3') {
          var otherVersion = 's60_2';
        } else if (PageVars.mapsVersion === 's60_2') {
          var otherVersion = 's60_3';
        }
        */

        /*if (MapsFunctions.version === otherVersion) {*/
          location.href=$('a#pricing_'+MapsFunctions.version).attr('href');
        /*} else if (MapsFunctions.version === 's40_1') {
          location.href=$('a#pricing_s40_1').attr('href'); 
        }*/
      } else if (deviceSelector==false) {
        $('#device_selector_head').show();
        $('#device_selected_head').hide();
      }
    }
  },

   /**
   * Toggles a customized heading for the Activation instructions pages
   * called by the device selector / parseDeviceXML wrapper
   * 
   * Fetches the locations of Maps 3.0, 2.0 or S40/1.0 Activation instructions pages from the HTML links
   *
   * @param changePage Boolean value indicating whether the user has to be taken to a
   *                   a different page. 
   */

  
 /** 
  * Complete feature list 
  */
 /*generateFeatureList : function() {
    //go through all features
		MapsFunctions.featuresTotal = $('feature', XMLData.features).length - 1;
    $(XMLData.features).find('feature').each(MapsFunctions.addFeatureHTML);
		MapsFunctions.featureTotal = -1;
  },*/

  /**
   * Show related features based on feature ID
   * used in the stand-alone feature pages as 
   * optional dynamic content
   * @param id String, feature ID defined in the Maps features XML e.g. 'walk', 'drive_3', etc
   */
  showRelatedFeatures : function(id) {
		//reset the feature counter
		MapsFunctions.featureCount = 0;
		$('#related_features')[0].style.visibility = "visible";
    //comma separated feature list
    f = $('feature#'+id+' related', XMLData.features).text();
    //feature array
    fa = f.split(',');
    
		//set global variable holding the length of the feature array
		MapsFunctions.featuresTotal = fa.length - 1;

    $('#features_container').empty();
    

    //go through feature IDs inside fa and print all features for the software version
    for(i in fa) {
			$(XMLData.features).find('feature#'+fa[i]).each(MapsFunctions.addFeatureHTML);
    }
		
		//reset the number of related features
		MapsFunctions.featuresTotal = -1;
  },

  updateScrollPane : function() {
    $('#device_selector').jScrollPane({
      dragMinHeight: "42", 
      dragMaxHeight: "300",
      showArrows: true
    });
  },

  showDeviceSelector : function() {
    //initiliaze the scrollpane
    $('#device_selector_container').show();
		$('#device_selector_head').hide();
  
		this.removeDeviceFilter();
  	MapsFunctions.updateScrollPane();
    //$('#device_selector').jScrollPane();
    //show the Scrollpane
    $('#device_selector').parent().show();
    $('#device_info').hide();
		$('#device_filter').val('');
    location.hash="#showselector=1";
    MapsFunctions.updateScrollPane();
  },
 
  /**
   * Hides the device selector and shows the device selector heading
   *
   * @param pricing Boolean, set when the page context is the pricing
   *                page
   */
  hideDeviceSelector : function(pricing) {
		//behave differently in pricing pages (different flow based on 
    //cookies being present)
    if (!pricing || (MapsFunctions.version != 's60_3' || MapsFunctions.device == null)) {
      $('#device_selector_head').show();
    }
		$('#device_selector_container').hide();
    location.hash="#";
    //if device info container exists
    if($('#device_info').length != 0) {
      if(MapsFunctions.device != null && (MapsFunctions.version == 's60_2' || MapsFunctions.version == 's60_3')) {
        this.showDeviceInfo(MapsFunctions.device);
      } else {
        $('#device_info').hide();
      }
    }
	},
  
  /**
   * Remove the device name cookie, modify the device specific Features
   * subheading, show the device selector
   *
   * @param headingID DOM id of subheading to be modified
   * @param headingObj Object containing the default and replaced text for the heading
   */
  clearDeviceSelection : function(context) {
    //simple scroll to top
    location.hash='#';

    this.clearCookies();
    if (context !== 'pricing' && context !== 'instructions') MapsFunctions.showDeviceFeatures('s60_3', null, true);
    this.showDeviceSelector();
    MapsFunctions.device = null;
  },

  /**
   * Resets the Maps cookies
   */
  clearCookies : function() {
    createCookie('maps_device', '', -1);
    createCookie('maps_version', '', -1);                 
  },

  /**
   * Handle filtering device list based on user input
   */ 
  filterDevice : function() {
    //get user input
    q = $('#device_filter').val().toLowerCase();

    if (q.length == 1) {
      MapsFunctions.removeDeviceFilter();
    }
    
    visiblePhones = 0;

    $('.phoneContainer').each(function() {
      //get the device name
      caption = $('.captionPhone', this).text().toLowerCase();
      if(caption.indexOf(q) != -1) { 
        $(this).show();
        visiblePhones++;
      } else {
        $(this).hide();
      }
    });
    if (visiblePhones == 0) $('#device_not_matched').show();
    else $('#device_not_matched').hide();

    MapsFunctions.updateScrollPane();
  },

  /**
   * Remove possible device filtering 
   */
  removeDeviceFilter : function() {                 
    $('.phoneContainer').each(function() {       
      $(this).show();    
    });
    $('#device_fitler').val('');
  },

  /** 
   * Callback function used to extract individual feature XML and generate HTML out of it
   *
   * @param count index of the currently handled feature in the feature list, 
   *              used for determining whether the index of the last shown feature is odd
   *              in which case a different CSS background is used for the feature list
   */
  addFeatureHTML : function(count) {
    name = $(this).find('name').text();
    img = $(this).find('icon').text();
    desc = $(this).find('desc').text();
    link = $(this).find('link').text();
    linkText = $(this).find('linktext').text();

		//fetch tag data
		tagId = $(this).find('tag_id').text();
		tagData = $('tagdata tag#'+tagId, XMLData.features);
		tagText = $('text', tagData).text();
		tagColor = $('color', tagData).text();
		tagIcon = $('icon', tagData).text();
    tagTooltip = $('tooltip', tagData).text();
    //tagTooltip = '<div style=\'float: left;\'>'+tagTooltip+'</div>';
		//tag-specific HTML code
		tagHTML = '';
		
		//if valid tag is specified, generate HTML for displaying the tag
		if (tagData.length == 1) {
		  tagHTML = '<div class="featureTag" ';
      if(tagTooltip != '') {
        tagHTML += 'onmouseover="Tip(\''+tagTooltip +'\')" onmouseout="UnTip()"';
      }
      tagHTML += '>'+
                '<img src="'+tagIcon+'" />' +
			          '<span style="color: '+tagColor+';">'+ tagText + '</span>' +
      			    '</div>';
		}

    //append device-specific URL parameter to the link going to specific feature page
    /*if(MapsFunctions.device !== '') {
      link+= '?device='+MapsFunctions.device;
    }*/
		
    //columnClass is a CSS class name for the feature column 
    //Can be left or right depending on whether count is odd or even

    //check if the feature number is odd or even, 
    //and create feature-rows accordingly
    if(MapsFunctions.featureCount%2 == 0) {
			if ( MapsFunctions.featureCount == MapsFunctions.featuresTotal && 
			     MapsFunctions.featuresTotal != -1 && 
					 MapsFunctions.featuresTotal%2 == 0) {
				featureRowHTML = '<div class="featureRowOdd">';
			} else {
	      featureRowHTML = '<div class="featureRow">';
		  }
      columnClass = 'leftColumn'; 
    } else {
      columnClass = '';
    }
   	 
    featureRowHTML += '<div class="featureColumn '+columnClass+'">' + tagHTML +
                    '<div class="featureIcon">' +
                      '<img src="'+img+'" />' +
                    '</div>' +
                    '<div class="featureText">' +
                      '<p><a href="' + link + '" class="featureLinkTop">' + name + '</a><br />' + desc + 
											'<a href="' + link + '" class="featureLinkBottom">'+linkText+'</a></p>'+
 								   '</div></div>';
    
    //always append 2 features at a time, unless the current feature is the last one
    if ( MapsFunctions.featureCount%2 == 1 
				 || MapsFunctions.featuresTotal == MapsFunctions.featureCount ) {
      featureRowHTML += '<div class="featureRowBottom"></div></div>';
      $(featureRowHTML).appendTo('#features_container');
    } else {
		}
    MapsFunctions.featureCount++; 
  }, 
  
  /** 
   * Repopulates and shows the device info box and hides the device selector
   *
   * @param device Device name, String
   */
  showDeviceInfo : function(device) {
    // find xml section with device = device
    $('devices > item:has(phone_id_txt:contains('+device+'))', XMLData.devices).
			 filter(function() { return $('phone_id_txt', this).text() == device; }).each(function() {
      image = $('image', this).text();

			version = $('maps_version', this).text();
			gps = $('gps', this).text();
			if ( gps == "true" ) {
				desc = $('featuredata '+version+' text_gps', XMLData.devices).text();
			} else {
			  desc = $('featuredata '+version+' text_no_gps', XMLData.devices).text();
			}
			desc = desc.replace(/\$phone/, device);
			
				
      //productpage = $('productpage', this).text();
			//get software version text 
			//swTxtTag = $('software_txt', this).text();
			swVersionTxt = $('maps_version_names '+version, XMLData.devices).text();

			//download location
			/*dlID = $('download_url', this).text();
			dlURL = $('item#macros > item#' + dlID + ' > url', XMLData.devices).text();
			dlPopup = $('item#macros > item#' + dlID + ' > popup', XMLData.devices).text();

			//set the the download location to either a JavaScript pop-up or a new page
			//by setting the download link's attributes
			if(dlPopup == "false") {
			  dlAttr = { href: dlURL, target: '_blank' };
			} else {
			  dlAttr = { href: "javascript:window.open('" + dlURL + "',"+
								         "'legal','left=20,top=20,width=510,height=525,toolbar=0,resizable=1');" +
												 "void(0);",
							    target: "_self" };
			}*/
     
      $('#device_info .staticPhone img').attr({ src : image });
			$('#device_info .staticPhone span#static_phone_caption').text(swVersionTxt);
			heading = $('uidata > text > deviceheading >' + version, XMLData.features).text().
				replace(/\$phone/, device);
      $('#device_info h3').text(heading);
      $('#device_info .descPhone p')[0].innerHTML = desc;
      //$('#productPageLink a').attr({ href : productpage });
			//$('#downloadSoftwareLink a').attr(dlAttr);
    });
		$('#device_selector_head').show();
    $('#device_selector_container').hide();
    $('#device_info').show();
    location.hash='#';
  },

  /** 
   * Displays device-specific features (for Maps 2.0 or Ovi Maps 3.0) on Features main page
   *
   * @param ver Maps software version. Valid values: s60_2, s60_3, s40_1, null
   * @param device Device name, string or null
   * @param selectorp Boolean value set to true, if showselector=1 hash parameter is present
   */
  showDeviceFeatures : function(ver, device, selectorp) {
    if (ver == null && device == null) {
      return;
    }

    //show hard-coded features list for Maps 3.0 or a dynamically generated one for Maps 2.0
    if (ver == 's60_3') {
      document.getElementById('features_container').style.display = 'none';
    	document.getElementById('features3_container').style.display = 'block';
    } else { 
      document.getElementById('features_container').style.display = 'block';
    	document.getElementById('features3_container').style.display = 'none';  
    }
    //get the number of currently selected features - used when checking whether the last feature row 
    //contains 1 or 2 features
    MapsFunctions.featuresTotal = $('features#' + ver + ' feature', XMLData.features).length - 1;
		//exception for s40 and s60 1.0 devices
		if ( ver == 's40_1' ) {
			location = $('page_locations > s40_features', XMLData.features).text();
			return;
		} else if ( ver == 's60_1' ) {
			location = $('page_locations > maps_1_features', XMLData.features).text();
			return;
		}
    
    this.modifyHtmlHeading('modifiable_heading', featureHeading);
    MapsFunctions.device = device;
    MapsFunctions.featureCount = 0;
    
    //only perform dynamic features generation for Maps 2.0
    if (ver == 's60_2') {
      $('#features_container').empty();
      //go through feature IDs inside fa and print all features for the software version
      $(XMLData.features).find('features#'+ver+' feature').each(MapsFunctions.addFeatureHTML);
    }
    //If the showselector=1 hashparameter is not present:
    //Show the device specific box and hide the device list
    if (!selectorp && device != null) this.showDeviceInfo(device);
    MapsFunctions.featuresTotal = -1;
  },
  
  //Displays default feature list
 /* showAllFeatures : function() {
	  //clear the URL hash params
		//location.hash =  '#';
    $('#features_container').empty();
    MapsFunctions.featureCount = 0;
    //we are appending HTML for 2 features (feature row) at the time
    this.featureRowHTML = '';
    
    //go through all features
    MapsFunctions.generateFeatureList();
    //$('features', XMLData.features).find('feature').each(MapsFunctions.addFeatureHTML);
    this.featureCount = 0;
    this.showDeviceSelector();

  },*/
  
  /** 
   * Add device name to SiFR heading if the user has selected the device of the same
   * version as the current page.
   *
   * @param version Maps version of the format 's60_1', 's60_2', 's60_3', 's40_1'
   */
  modifyHeading : function(version) {
    this.device = readCookie('maps_device');
    MapsFunctions.version = readCookie('maps_version');
    if(MapsFunctions.version === version && this.device != null) {
      //add device name to the page heading requires the H1 element with 
      //id #siffr71 to contain string "$phone" which is used as placholder
      this.t = $('#sifr71').text();
      this.t = this.t.replace(/\$phone/, this.device);
      $('#sifr71').text(this.t);

      //check the length of the title - if length too long use the smaller version of heading SiFR styles
      if(this.t.length > 28) {
        $('#sifr71').removeClass('sifr').addClass('sifrSmaller');
      }

      //hide the default heading
      $('#sifr70')[0].style.display="none";
      $('#sifr71')[0].style.visibility="visible";
    } else {
      //show default heading if valid Maps cookie was not present
      $('#sifr71')[0].style.display="none";
    }
  },

  /** 
   * Replace the default heading with a modified one
   *
   * @param elementId ID of the heading element
   * @param headingObj Object containing the default text and modified text 
   *                   for the heading
   */
  modifyHtmlHeading : function(elementId, headingObj, version, pricingPage) {
    this.device = readCookie('maps_device');
    MapsFunctions.version = readCookie('maps_version');
    //alert("Device: "+ this.device + "\nVersion: " + MapsFunctions.version);
   
    if(MapsFunctions.version != null && this.device != null &&
       (MapsFunctions.version == 's60_2' || MapsFunctions.version == 's60_3' || 
        ( pricingPage==true && MapsFunctions.version === 's40_1' ))) {
      this.t = headingObj.replacedText;
      this.t = this.t.replace(/\$phone/, this.device);
      $('#'+elementId).text(this.t);
    } else {
      //show default heading if valid Maps cookie was not present
      this.t = headingObj.defaultText;
      $('#'+elementId).text(this.t);
    } 
  },

  /** 
   * Generate screenshot navigation toolbar
   * requires that <img class="scr" ... /> HTML elements containing screenshots are present
	 * @param parentDivId ID of the container DIV in which to generate dynamic elements
   */
	generateScreenshotNavi : function(parentDivId) {
		//number of screenshots in the container (images of class="scr")
		nScr = $('#'+parentDivId+' .scr').length;
		//don't show navi if one or less screenshots are present
		if (nScr <= 1) {
			 return;
		}
		
		//navi graphics
    g = $('featuredata > uidata > graphics', XMLData.features);
		navLeft = $('scrnavi_left', g).text();
		navRight = $('scrnavi_right', g).text();
		navActive = $('scrnavi_active', g).text();
		navInactive = $('scrnavi_inactive', g).text();

		//HTML code for the screenshot navi container and UI
		scrNaviHTML = '<div class="scrNaviOuter"><div class="scrNaviWrap">'+
									'<ul><li><img src="' + navLeft + '" /></li>';
		for(i = 0; i < nScr; i++) {
			if(i == 0) {
				 attr = 'src="' + navActive + '" selected="true" nr="0"';
			} else {
				 attr = 'src="'+ navInactive +'" selected="false" nr="'+ i +'"';
			}
			scrNaviHTML += '<li><img class="scrNaviButton" ' + attr + '/><li>';
		}
		scrNaviHTML += '<li><img src="'+ navRight +'" /></li></ul></div></div>';
	
		//parentDivId = id of the screenshot containing box
		$(scrNaviHTML).appendTo('#'+parentDivId);

	 
		//screenshotnavi events
		$('#'+parentDivId +' .scrNaviButton').hover(
			function() {
				$(this).attr({ src: navActive });
			},
			function() {
				if($(this).attr('selected') == "false")
					$(this).attr({ src: navInactive });
			} 
		);

		$('#'+parentDivId +' .scrNaviButton').click(
			function() {
				$('#'+parentDivId+' .scr').css({ visibility: 'hidden' });
				var nr = $(this).attr("nr");
				$('#'+parentDivId +' .scr')[nr].style.visibility = "visible";
				$('#'+parentDivId +' .scrNaviButton').attr({ src: navInactive, selected: "false" });
				$(this).attr({ src: navActive, selected: "true" });
			}
		);
	}
}
//set the default Maps version and device name info
MapsFunctions.version = 's60_3';
MapsFunctions.device = null;

//fetch the cookies and assign them to variables
if((dev = readCookie('maps_device')) != null) MapsFunctions.device = dev; 
if((ver = readCookie('maps_version')) != null) MapsFunctions.version = ver;
