/**
 * JavaScript for RadioTime widget
 * Asynchronously queries RadioTime compatibility service and returns 
 * JSON list of matching station titles, if any exist.
 *
 * @see radiotime.html
 * @see radiotime.css
 * @see http://services.radiotime.com/json/SearchJson.aspx?action=compat&callback=RadioTimeWidget.displayResults&partnerId=16&query=97
 *
 * @link http://www.radiotime.com/
 * @link http://www.logitech.com/
 * @contact Matthew_Martin@logitech.com
 *
 */

/**
 * Implementation specific variables 
 * 
 * edit these values (right side of colon ':' ) to change widget behavior
 */
var gVars = {

  // XXX application strings
  "lang": {
    "TITLE":                     'Logitech<span class="SuperScript">&reg;</span> Squeezebox<span class="SuperScript">&trade;</span> Station Search',
    "INSTRUCTIONS":              "Enter a radio station keyword (such as call sign, name, or frequency) and hit enter to see if your station is available on Squeezebox.",
    "PROMPT":                    "Check for your station now!",
    "RESULTS":                   "results",
    "NO_RESULTS_TEXT":           "Sorry, we couldn't locate any radio stations matching your search. Please try a different search.",
    "TRY_AGAIN":                 "Please try a different search.",
    "RESULT_AVAILABLE":          "Available on Squeezebox.",
    "RESULT_UNAVAILABLE":        "Not available on Squeezebox.",
    "TEXT_INPUT_DEFAULT_VALUE":  "Examples: kqed, 5230, paris, jazz...",
    "INCORRECT_RESULTS":         "Incorrect results?",
    "FEEDBACK_LINK_TEXT":        "Notify RadioTime.",
    "RESULTS_FOUND":             "results found.",
    "NO_RESULTS":                "Sorry, we couldn't find any radio stations like that. Please try a different search.<br/><br/>Something we're missing? Click the link below to let us know."
  },

  // ids
  "title_id":                    "rtwidget_title",
  "instructions_id":             "rtwidget_instructions",
  "text_input_id":               "rtwidget_text_input",
  "text_input_container_id":     "rtwidget_text_input_container",
  "no_results_text_id":          "rtwidget_no_results_text",
  "available_text_id":           "rtwidget_available_text",
  "unavailable_text_id":         "rtwidget_unavailable_text",
  "feedback_question_id":        "rtwidget_feedback_question",
  "feedback_link_text_id":       "rtwidget_feedback_link_text",
  "results_count_number_id":     "rtwidget_results_count_number",
  "results_found_text_id":       "rtwidget_results_found_text",
  "no_results_text_id":          "rtwidget_no_results_text",
  "poweredby_link_id":           "rtwidget_poweredby_link",
  "container_id":                "rtwidget_container",
  "results_container_id":        "rtwidget_results",
  "results_list_id":             "rtwidget_results_list",
  "result_template_id":          "rtwidget_result_template",
  "available_icon_img_id":       "rtwidget_available_icon",
  "unavailable_icon_img_id":     "rtwidget_unavailable_icon",
  "poweredby_icon_img_id":       "rtwidget_poweredby_icon",

  // classes
  "class_available":             "Available",
  "class_unavailable":           "Unavailable",
  "class_no_results":            "NoResults",
  "class_has_results":           "HasResults",
  "class_active":                "Active",
  "class_inactive":              "Inactive",

  // misc options
  "image_path":                  "", // optional path to image assets e.g. /images/
  "css_path":                    "", // optional path to css assets e.g. /css/
  "radiotime_service_url_base":  "http://services.radiotime.com/json/SearchJson.aspx?action=compat&callback=RadioTimeWidget.displayResults&partnerId=16&query=",
  "available_icon_img_src":      "check_icon_green_39x31.gif",
  "unavailable_icon_img_src":    "exclamation_icon_orange_38x35.gif",
  "poweredby_icon_img_src":      "powered_by_radiotime_79x23.gif",

  "radiotime_img_height":        100,
  "radiotime_img_width":         100,
  "radiotime_contact_us_href":   "http://radiotime.com/contact-us.aspx",
  "radiotime_poweredby_link":    "http://radiotime.com/",

  // replacements for template
  "result_station_pattern":      "%{rtwidget_result_station_title}",
  "result_available_pattern":    "%{rtwidget_result_available_switch_class}"

};


if( RadioTimeWidget == undefined )
{
  var RadioTimeWidget = {

/**
 * Appends a CSS stylesheet to the current document
 *
 * @param String $cssUrl URL or path of stylesheet
 * @return null
 */
    addCss : function( cssUrl ) {
      stylesheet = document.createElement("link");
      stylesheet.rel = "stylesheet";
      stylesheet.type = "text/css";
      stylesheet.href = gVars.css_path + cssUrl;
      stylesheet.media = "all";
      document.lastChild.firstChild.appendChild(stylesheet);
    },

/**
 * Retreives JSON asynchronously and stores result in javascript code block
 *
 * @param String $jsonUrl The URL to retreive JSON from
 * @return null
 */
    getJson : function( jsonUrl ) {
      var script = document.createElement('script');
      script.src = jsonUrl;
      
      // Cope with missing head declaration in HTML
      var head = document.getElementsByTagName('head');
      if( head.length == 0 )
        document.getElementById('rt_widget').appendChild(script);
      else
        head[0].appendChild(script);

    },

/**
 * Convenient alias to get element by id
 *
 * @param Mixed $element An element object or id string
 */
    $: function( element ) {
      if( typeof( element ) != 'string' )
        return element;
      return document.getElementById( element );
    },

    hasClass: function( element, className ) {
      var ele = RadioTimeWidget.$( element ); 
      return ele.className.match( new RegExp( '(\\s|^)' + className + '(\\s|$)' ) );
    },

    addClass: function( element, className ) {
      // already has this class name
      if( RadioTimeWidget.hasClass( element, className ) ) 
        return false;
      // append class name
      var ele = RadioTimeWidget.$( element );
      ele.className += " " + className;
      return true;
    },

    removeClass: function( element, className ) {
      var ele = RadioTimeWidget.$( element );
      // remove if exists
      if( RadioTimeWidget.hasClass( element, className ) ) {
        var reg = new RegExp( '(\\s|^)' + className + '(\\s|$)' );
        ele.className = ele.className.replace( reg,' ' );
        return true;
      }
      return false;
    }, 

/**
 * Asynchronously request stations matching text box value
 * @return Boolean false Returns false to use as onclick action
 */
    searchForStations: function() {
      RadioTimeWidget.getJson( gVars.radiotime_service_url_base + RadioTimeWidget.$( gVars.text_input_id ).value );
      return false;
    },

/**
 * Append result item to HTML
 *
 * @param Object $result A JSON result object
 * @param String $html The current HTML string to append to
 * @return null
 */
    addResult: function( result ) {

      // grab the template
      var resultElementString = RadioTimeWidget.$( gVars.result_template_id ).innerHTML;

      // replace all ids with blank so no duplicate ID's exist in DOM once copied
      resultElementString = resultElementString.replace(/id=".+"/g, "" );

      // fill in the station title
      resultElementString = resultElementString.replace( new RegExp( gVars.result_station_pattern ), result.Title );

      // add Available or Unavailable class
      var className = gVars.class_available;
      if( !result.Available )
        className = gVars.class_unavailable;

      resultElementString = resultElementString.replace( new RegExp( gVars.result_available_pattern ), className ); 

      // append result to list
      var list = RadioTimeWidget.$( gVars.results_list_id );
      list.innerHTML += resultElementString;

    },

/**
 * Parse JSON results and display them
 * 
 * @param Object $results JSON results object
 * @return null;
 */
    displayResults: function( results ) {

      RadioTimeWidget.removeClass( gVars.container_id, gVars.class_inactive );
      RadioTimeWidget.addClass( gVars.container_id, gVars.class_active );

      // clear results
      RadioTimeWidget.$( gVars.results_container_id ).innerHtml = "";
  
      var count = 0;
  
      // no results
      if( !results || results.ResultCount == 0 || results.Results.length == 0 ) {

        RadioTimeWidget.addClass( gVars.container_id, gVars.class_no_results );
        RadioTimeWidget.removeClass( gVars.container_id, gVars.class_has_results );

      // process list of results
      } else {

        // sort by availability, put available results first
        var compat = Array();
        var notCompat = Array();
        for( x in results.Results ) {
          var result = results.Results[x];
          if( result.Available ) {
            compat.push( result );
            continue;
          }
          notCompat.push( result );
        }
        results.Results = compat.concat( notCompat );

        // clear old results
        RadioTimeWidget.$( gVars.results_list_id ).innerHTML = '';

        RadioTimeWidget.addClass( gVars.container_id, gVars.class_has_results );
        RadioTimeWidget.removeClass( gVars.container_id, gVars.class_no_results );

        for( var i = 0; i < results.Results.length; i++ ) {
          RadioTimeWidget.addResult( results.Results[i] );
        }
    
        RadioTimeWidget.$( gVars.results_count_number_id ).innerHTML = results.Results.length;

      }
    },

    setText: function( element, innerHtml ) {

      var ele = RadioTimeWidget.$( element );
      ele.innerHTML = innerHtml;

    },

/**
 * Initialize the form and such
 *
 * @return null
 */

    init: function() {

      // register onkeypress event handler
      var onkeypressInlineEvent = "if(event.keyCode == 13){ RadioTimeWidget.searchForStations(); return false; }";
      var container = RadioTimeWidget.$( gVars.text_input_container_id );
      var newInputHtml = container.innerHTML.replace( /onkeypress=""/, 'onkeypress="' + onkeypressInlineEvent + '"' );
      container.innerHTML = newInputHtml;

      // set state
      RadioTimeWidget.addClass( gVars.container_id, gVars.class_inactive );
      RadioTimeWidget.addClass( gVars.text_input_id, gVars.class_inactive );

      // set language texts
      RadioTimeWidget.setText( gVars.title_id,               gVars.lang.TITLE );
      RadioTimeWidget.$( gVars.text_input_id ).value       = gVars.lang.TEXT_INPUT_DEFAULT_VALUE;
      RadioTimeWidget.setText( gVars.instructions_id,        gVars.lang.INSTRUCTIONS );
      RadioTimeWidget.setText( gVars.no_results_text_id,     gVars.lang.NO_RESULTS );
      RadioTimeWidget.setText( gVars.available_text_id,      gVars.lang.RESULT_AVAILABLE );
      RadioTimeWidget.setText( gVars.unavailable_text_id,    gVars.lang.RESULT_UNAVAILABLE );
      RadioTimeWidget.setText( gVars.feedback_question_id,   gVars.lang.INCORRECT_RESULTS );
      RadioTimeWidget.setText( gVars.feedback_link_text_id,  gVars.lang.FEEDBACK_LINK_TEXT );
      RadioTimeWidget.setText( gVars.results_found_text_id,  gVars.lang.RESULTS_FOUND );
      RadioTimeWidget.setText( gVars.no_results_text_id,     gVars.lang.NO_RESULTS );
      
      // set misc data such as img src, link href
      RadioTimeWidget.$( gVars.feedback_link_text_id ).href  = gVars.radiotime_contact_us_href;
      RadioTimeWidget.$( gVars.poweredby_link_id ).href      = gVars.radiotime_poweredby_link;
      RadioTimeWidget.$( gVars.available_icon_img_id ).src   = gVars.image_path + gVars.available_icon_img_src;
      RadioTimeWidget.$( gVars.unavailable_icon_img_id ).src = gVars.image_path + gVars.unavailable_icon_img_src;
      RadioTimeWidget.$( gVars.poweredby_icon_img_id ).src   = gVars.image_path + gVars.poweredby_icon_img_src;

      // register click event handler
      RadioTimeWidget.$( gVars.text_input_id ).onclick       = RadioTimeWidget.handleClickEvent;

    }

  };  // end RadioTimeWidget definition
}


// Need this style definition to use inline event handling

/**
 * Handle keypress event
 * @return Boolean false
 */
  RadioTimeWidget.handleKeypressEvent = function() {
    RadioTimeWidget.searchForStations(); 
    return false;
  }

/**
 * Handle click event
 * @return null
 */
  RadioTimeWidget.handleClickEvent = function() {

    var input = RadioTimeWidget.$( gVars.text_input_id );

    // clear the help text
    if( input.value == gVars.lang.TEXT_INPUT_DEFAULT_VALUE )
      input.value = '';

    RadioTimeWidget.removeClass( gVars.text_input_id, gVars.class_inactive );

  }

RadioTimeWidget.addCss( 'radiotime.css' );
RadioTimeWidget.init();



