/*
  Original credit to James Smith at http://loopj.com/2009/04/25/jquery-plugin-tokenizing-autocomplete-text-entry/
  with modifications from a commentor via http://otisbean.com/dropbox/jquery.tokeninput.js
  and modifications on or around 2009-05-13 to handle providing the search query as the
  first available option in search results.
  
  Author stated the license is GPL2, but original doesn't contain the copyright notice. Author's
  stated intent is just to retain original authorship, which is provided at the beginning of
  this comment.
*/


(function($) {

$.fn.tokenInput = function (url, options) {
    var settings = $.extend({
        url: url,
        hintText: "Type in a search term",
        noResultsText: "No results",
        searchingText: "Searching...",
        searchDelay: 300,
        minChars: 2
    }, options);
    
    settings.classes = $.extend({
        tokenList: "token-input-list",
        token: "token-input-token",
        tokenDelete: "token-input-delete-token",
        selectedToken: "token-input-selected-token",
        highlightedToken: "token-input-highlighted-token",
        dropdown: "token-input-dropdown",
        dropdownItem: "token-input-dropdown-item",
        dropdownItem2: "token-input-dropdown-item2",
        selectedDropdownItem: "token-input-selected-dropdown-item",
        inputToken: "token-input-input-token"
    }, options.classes);

    // customization to allow a reference to the token list so that it can populate items
    var self = this;
    
    return this.each(function () {
        var list = new $.TokenList(this, settings);
        self.list = list;
    });
};

$.TokenList = function (input, settings) {
    //
    // Variables
    //

    // Input box position "enum"
    var POSITION = {
        BEFORE: 0,
        AFTER: 1,
        END: 2
    };

    // Keys "enum"
    var KEY = {
        BACKSPACE: 8,
        TAB: 9,
        RETURN: 13,
        ESC: 27,
        LEFT: 37,
        UP: 38,
        RIGHT: 39,
        DOWN: 40,
        COMMA: 188
    };

    // Save the tokens
    var saved_tokens = [];

    // Basic cache to save on db hits
    var cache = new $.TokenList.Cache();

    // Keep track of the timeout
    var timeout;

    // Create a new text input an attach keyup events
    var input_box = $("<input type=\"text\">")
        .css({
            outline: "none"
        })
        .focus(function () {
            show_dropdown_hint();
        })
        .blur(function () {
            hide_dropdown();
            // FIXME this was wrapped in "if(!selected_dropdown_item) {}", but
            // selected_dropdown_item is pretty much always non-null, which
            // meant that the dropdown was never hidden on blur.
        })
        .keydown(function (event) {
            var previous_token;
            var next_token;

            switch(event.keyCode) {
                case KEY.LEFT:
                case KEY.RIGHT:
                case KEY.UP:
                case KEY.DOWN:
                    if(!$(this).val()) {
                        previous_token = input_token.prev();
                        next_token = input_token.next();

                        if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) {
                            // Check if there is a previous/next token and it is selected
                            if(event.keyCode == KEY.LEFT || event.keyCode == KEY.UP) {
                                deselect_token($(selected_token), POSITION.BEFORE);
                            } else {
                                deselect_token($(selected_token), POSITION.AFTER);
                            }
                        } else if((event.keyCode == KEY.LEFT || event.keyCode == KEY.UP) && previous_token.length) {
                            // We are moving left, select the previous token if it exists
                            select_token($(previous_token.get(0)));
                        } else if((event.keyCode == KEY.RIGHT || event.keyCode == KEY.DOWN) && next_token.length) {
                            // We are moving right, select the next token if it exists
                            select_token($(next_token.get(0)));
                        }
                    } else {
                        var dropdown_item = null;

                        if(event.keyCode == KEY.DOWN || event.keyCode == KEY.RIGHT) {
                            dropdown_item = $(selected_dropdown_item).next();
                        } else {
                            dropdown_item = $(selected_dropdown_item).prev();
                        }

                        if(dropdown_item.length) {
                            select_dropdown_item(dropdown_item);
                        }
                        return false;
                    }
                    break;

                case KEY.BACKSPACE:
                    previous_token = input_token.prev();

                    if(!$(this).val().length) {
                        if(selected_token) {
                            delete_token($(selected_token));
                        } else if(previous_token.length) {
                            select_token($(previous_token.get(0)));
                        }

                        return false;
                    } else if($(this).val().length == 1) {
                        hide_dropdown();
                    } else {
                        // set a timeout just long enough to let this function finish.
                        setTimeout(function() {do_search(true); }, 5);
                    }
                    break;

                case KEY.RETURN:
                case KEY.COMMA:
                    if(selected_dropdown_item) {
                        add_token($(selected_dropdown_item));
                        return false;
                    }
                    break;

                case KEY.TAB:
                  if(selected_dropdown_item) {
                    add_token($(selected_dropdown_item));
                    return true;
                  }
                  break;

                case KEY.ESC:
                  hide_dropdown();
                  return true;

                default:
                    if(is_printable_character(event.keyCode)) {
                      // set a timeout just long enough to let this function finish.
                      setTimeout(function() {do_search(false); }, 5);
                    }
                    break;
            }
        });

    // Keep a reference to the original input box
    var hidden_input = $(input)
                           .hide()
                           .focus(function () {
                               input_box.focus();
                           })
                           .blur(function () {
                               input_box.blur();
                           });

    // Keep a reference to the selected token and dropdown item
    var selected_token = null;
    var selected_dropdown_item = null;

    // The list to store the token items in
    var token_list = $("<ul />")
        .addClass(settings.classes.tokenList)
        .insertAfter(hidden_input)
        .click(function (event) {
            var li = get_element_from_event(event, "li");
            if(li && li.get(0) != input_token.get(0)) {
                toggle_select_token(li);
                return false;
            } else {
                input_box.focus();

                if(selected_token) {
                    deselect_token($(selected_token), POSITION.END);
                }
            }
        })
        .mouseover(function (event) {
            var li = get_element_from_event(event, "li");
            if(li && selected_token !== this) {
                li.addClass(settings.classes.highlightedToken);
            }
        })
        .mouseout(function (event) {
            var li = get_element_from_event(event, "li");
            if(li && selected_token !== this) {
                li.removeClass(settings.classes.highlightedToken);
            }
        })
        .mousedown(function (event) {
            // Stop user selecting text on tokens
            var li = get_element_from_event(event, "li");
            if(li){
                return false;
            }
        });


    // The list to store the dropdown items in
    var dropdown = $("<div>")
        .addClass(settings.classes.dropdown)
        .insertAfter(token_list)
        .hide();

    // The token holding the input box
    var input_token = $("<li />")
        .addClass(settings.classes.inputToken)
        .appendTo(token_list)
        .append(input_box);

    // // If the input had any values initially, make tokens for them
    // if (hidden_input.val()) {
    //   var original_vals = hidden_input.val().
    //     replace(/[, ]+/g, ' ').replace(/^\s+|\s+$/g, '').split(/ /);
    //   for ( var i = 0; i < original_vals.length; i++) {
    //     // TODO consider calling the server or checking the local cache to
    //     // find the correct "name" values for the ids.
    //     insert_token(original_vals[i], original_vals[i]);
    //   }
    //   // Canonicalize the values in the hidden input
    //   hidden_input.val(original_vals.join(',') + ',');
    // }

    //
    // Functions
    //

    function is_printable_character(keycode) {
        if((keycode >= 48 && keycode <= 90) ||      // 0-1a-z
           (keycode >= 96 && keycode <= 111) ||     // numpad 0-9 + - / * .
           (keycode >= 186 && keycode <= 192) ||    // ; = , - . / ^
           (keycode >= 219 && keycode <= 222)       // ( \ ) '
          ) {
              return true;
          } else {
              return false;
          }
    }

    // Get an element of a particular type from an event (click/mouseover etc)
    function get_element_from_event (event, element_type) {
        var target = $(event.target);
        var element = null;

        if(target.is(element_type)) {
            element = target;
        } else if(target.parent(element_type).length) {
            element = target.parent(element_type+":first");
        }

        return element;
    }
    
    this.clear_list = function()
    {
      token_list.find('.' + settings.classes.token).remove();
      hidden_input.val('');
    }
    
    this.create_and_add_token = function(id, value, useCallback)
    {
      if(typeof(useCallback) == 'undefined')
        useCallback = true;
      
      create_token(id, value, useCallback);
      update_hidden_el(id);
    }
    
    this.create_and_add_token_without_callback = function(id, value)
    {
      this.create_and_add_token(id, value, false);
    }
    
    this.delete_token = function(token)
    {
      delete_token(token);
    }
    
    this.delete_token_without_callback = function(token)
    {
      delete_token(token, false);
    }
    
    this.update_token = function(token, id, value)
    {
      $.data(token.get(0), "tokeninput", {"id": id, "name": value});
    }
    
    this.get_tokens = function()
    {
      tokens = []
      token_list.find('.' + settings.classes.token).each(function() { 
        tokens.push($.data(jQuery(this).get(0), 'tokeninput'))
      })
      
      return tokens;
    }
    
    // Inner function to a token to the list
    function create_token(id, value, useCallback) {
      var this_token = $("<li><p>"+ value +"</p> </li>")
      .addClass(settings.classes.token)
      .insertBefore(input_token);

      // The 'delete token' button
      $("<span>x</span>")
          .addClass(settings.classes.tokenDelete)
          .appendTo(this_token)
          .click(function () {
              delete_token($(this).parent());
              return false;
          });

      $.data(this_token.get(0), "tokeninput", {"id": id, "name": value});
      
      if(typeof(useCallback) == 'undefined')
        useCallback = true;
      
      if(settings.onAdded && useCallback)
        settings.onAdded(this_token);

      return this_token;
    }
    
    function update_hidden_el(val)
    {
        var id_string = val + ","
        hidden_input.val(hidden_input.val() + id_string);
    }
    
    // Add a token to the token list based on user input
    function add_token (item) {
        var li_data = $.data(item.get(0), "tokeninput");
        var this_token = create_token(li_data.id, li_data.name);

        
        // Clear input box and make sure it keeps focus
        input_box
            .val("")
            .focus();

        // Don't show the help dropdown, they've got the idea
        hide_dropdown();

        // Save this token id
        update_hidden_el(li_data.id);
    }

    // Select a token in the token list
    function select_token (token) {
        token.addClass(settings.classes.selectedToken);
        selected_token = token.get(0);

        // Hide input box
        input_box.val("");

        // Hide dropdown if it is visible (eg if we clicked to select token)
        hide_dropdown();
    }

    // Deselect a token in the token list
    function deselect_token (token, position) {
        token.removeClass(settings.classes.selectedToken);
        selected_token = null;

        if(position == POSITION.BEFORE) {
            input_token.insertBefore(token);
        } else if(position == POSITION.AFTER) {
            input_token.insertAfter(token);
        } else {
            input_token.appendTo(token_list);
        }

        // Show the input box and give it focus again
        input_box.focus();
    }

    // Toggle selection of a token in the token list
    function toggle_select_token (token) {
        if(selected_token == token.get(0)) {
            deselect_token(token, POSITION.END);
        } else {
            if(selected_token) {
                deselect_token($(selected_token), POSITION.END);
            }
            select_token(token);
        }
    }

    // Delete a token from the token list
    function delete_token (token, useCallback) {
        // Remove the id from the saved list
        var token_data = $.data(token.get(0), "tokeninput");
        //saved_tokens.splice($.inArray(saved_tokens, token_data.id), 1);

        // Delete the token
        token.remove();
        selected_token = null;

        // Show the input box and give it focus again
        input_box.focus();

        // Delete this token's id from hidden input
        var str = hidden_input.val()
        var start = str.indexOf(token_data.id+",");
        var end = str.indexOf(",", start) + 1;

        if(end >= str.length) {
            hidden_input.val(str.slice(0, start));
        } else {
            hidden_input.val(str.slice(0, start) + str.slice(end, str.length));
        }
        
        if(typeof(useCallback) == 'undefined')
          useCallback = true;
        
        if(settings.onRemoved && useCallback)
          settings.onRemoved(token_data);
    }

    // Hide and clear the results dropdown
    function hide_dropdown () {
        dropdown.hide().empty();
        selected_dropdown_item = null;
    }

    function show_dropdown_searching () {
        dropdown
            .html("<p>"+settings.searchingText+"</p>")
            .show();
    }

    function show_dropdown_hint () {
        dropdown
            .html("<p>"+settings.hintText+"</p>")
            .show();
    }

    // Highlight the query part of the search term
	function highlight_term(value, term) {
		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<em>$1</em>");
	}

    // Populate the results dropdown with some results
    function populate_dropdown (query, results) {
        dropdown.empty();
        var dropdown_ul = $("<ul>")
            .appendTo(dropdown)
            .mouseover(function (event) {
                select_dropdown_item(get_element_from_event(event, "li"));
            })
            .click(function (event) {
                // moved following line to mousedown because IE wasn't calling it
                // add_token(get_element_from_event(event, "li"));
            })
            .mousedown(function (event) {
                // Stop user selecting text on tokens
                add_token(get_element_from_event(event, "li"));
                return false;
            })
            .hide();
        
        var no_results = false;
        if(results.length == 0)
          no_results = true;
        
        // populate first entry with query. It can already be set if coming from the cache
        if(no_results || results[0].name != query)
          results.unshift({'name': query, 'id': query});
        
        for(var i in results) {
            if (results.hasOwnProperty(i)) {
                var this_li = $("<li>"+highlight_term(results[i].name, query)+"</li>")
                                  .appendTo(dropdown_ul);

                if(i%2) {
                    this_li.addClass(settings.classes.dropdownItem);
                } else {
                    this_li.addClass(settings.classes.dropdownItem2);
                }

                if(i == 0) {
                    select_dropdown_item(this_li);
                }

                $.data(this_li.get(0), "tokeninput", {"id": results[i].id, "name": results[i].name});
            }
        }
        
        if(no_results)
        {
          dropdown.append($("<p>"+settings.noResultsText+"</p>"));
        }
        
        dropdown.show();
        dropdown_ul.slideDown("fast");
    }

    // Highlight an item in the results dropdown
    function select_dropdown_item (item) {
        if(item) {
            if(selected_dropdown_item) {
                deselect_dropdown_item($(selected_dropdown_item));
            }

            item.addClass(settings.classes.selectedDropdownItem);
            selected_dropdown_item = item.get(0);
        }
    }

    // Remove highlighting from an item in the results dropdown
    function deselect_dropdown_item (item) {
        item.removeClass(settings.classes.selectedDropdownItem);
        selected_dropdown_item = null;
    }

    // Do a search and show the "searching" dropdown if the input is longer
    // than settings.minChars
    function do_search(immediate) {
        var query = input_box.val().trim();
        if (query && query.length) {
            if(selected_token) {
                deselect_token($(selected_token), POSITION.AFTER);
            }
            if (query.length >= settings.minChars) {
                show_dropdown_searching();
                if (immediate) {
                    run_search(query);
                } else {
                    clearTimeout(timeout);
                    timeout = setTimeout(function() {run_search(query)}, settings.searchDelay);
                }
            } else {
                hide_dropdown();
            }
        }
    }

    // Do the actual search
    function run_search(query) {
        var cached_results = cache.get(query);
        if(cached_results) {
            populate_dropdown(query, cached_results);
        } else {
            $.get(settings.url, {"q": query }, function (results) {
              cache.add(query, results);
              populate_dropdown(query, results);
            }, "json");
        }
    }
};

// Really basic cache for the results
$.TokenList.Cache = function (options) {
    var settings = $.extend({
        max_size: 10
    }, options);

    var data = {};
    var size = 0;

    var flush = function () {
        data = {};
        size = 0;
    };

    this.add = function (query, results) {
        if(size > settings.max_size) {
            flush();
        }

        if(!data[query]) {
            size++;
        }

        data[query] = results;
    };

    this.get = function (query) {
        return data[query];
    };
};

})(jQuery);


// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

function prevent_enter_key_submit(els)
{
  jQuery(els).bind("keypress", function(e) {
    if(e.keyCode == 13)
      return false;
  })
}

function getParam( name ){  
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");  
  var regexS = "[\\?&]"+name+"=([^&#]*)";  
  var regex = new RegExp( regexS );  
  var results = regex.exec( window.location.href ); 
  if( results == null )    return "";  
  else    return results[1];
}

function add_text_select_on_click(input_id)
{
  if(!input_id)
    return;
  else if(input_id instanceof Array)
  {
    for(var i=0; i<input_id.length; ++i)
      add_text_select_on_click(input_id[i]);
    return;
  }
  else if(typeof(input_id) != 'string')
    return;
  
  if(input_id.charAt(0) != '#')
    input_id = '#' + input_id;
  
  jQuery(input_id).focus(select_on_click).click(select_on_click);
}

function select_on_click() { 
  if(this.select) 
    this.select(); 
}

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

/* modification to the autocompeleter out of script.aculo.us */
Autocompleter.Base.addMethods({
  /* MarkS changed this from scrollIntoView(true) so the page doesn't jump around when you use arrows */
    markPrevious: function() {
        if(this.index > 0) this.index--
          else this.index = this.entryCount-1;
        this.getEntry(this.index).scrollIntoView(false);
      }, 
  /* MarkS changed test to be more than 1 - there is always a default item that is hidden. */
    render: function() {
      if(this.entryCount > 1) {
        for (var i = 0; i < this.entryCount; i++)
          this.index==i ? 
            Element.addClassName(this.getEntry(i),"selected") : 
            Element.removeClassName(this.getEntry(i),"selected");
        if(this.hasFocus) { 
          this.show();
          this.active = true;
        }
      } else {
        this.active = false;
        this.hide();
      }
    }
});

Autocompleter.Local.addMethods({
    setOptions: function(options) {
      this.options = Object.extend({
        choices: 10,
        partialSearch: true,
        partialChars: 2,
        ignoreCase: true,
        fullSearch: false,
        selector: function(instance) {
          var ret       = []; // Beginning matches
          var partial   = []; // Inside matches
          var entry     = instance.getToken();
          var count     = 0;

      /* MarkS adding typed in text as an option - trying to hide it, too. */
      ret.push("<li class='default'>" + entry + "</li>");

          for (var i = 0; i < instance.options.array.length &&  
            ret.length < instance.options.choices ; i++) { 

            var elem = instance.options.array[i];
            var foundPos = instance.options.ignoreCase ? 
              elem.toLowerCase().indexOf(entry.toLowerCase()) : 
              elem.indexOf(entry);

            while (foundPos != -1) {
              if (foundPos == 0 && elem.length > entry.length) { 
                ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
                  elem.substr(entry.length) + "</li>");
                break;
              } else if (entry.length >= instance.options.partialChars && 
                instance.options.partialSearch && foundPos != -1) {
                if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
                  partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
                    elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
                    foundPos + entry.length) + "</li>");
                  break;
                }
              }

              foundPos = instance.options.ignoreCase ? 
                elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
                elem.indexOf(entry, foundPos + 1);

            }
          }
          if (partial.length)
            ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
          return "<ul>" + ret.join('') + "</ul>";
        },
        
        afterUpdateElement: function(el, selectedEl) { jQuery(el).parents('form').submit(); }
      }, options || { });
    }
  });

var playerLoadedCheck = function(instanceId){
	try {
	 var el = document.getElementById(instanceId + '_anchor');
	 for(var i=0; i<el.childNodes.length; ++i)
	 {
	   if(el.childNodes[i].nodeType == 3)
	     el.replaceChild(document.createTextNode(''), el.childNodes[i]);
	 }
	} catch(e) { console.error(e); }
}


/* An onclick listener that will reload the playerWrapperId content based on the
   clipUrl passed. The anchor is necessary to update it's parent element with the
   classname 'clip'
*/
var onClipTriggerClick = function(anchor, clipUrl) {
  jQuery('.clip').removeClass('playing');
  jQuery(anchor).parents('.clip').addClass('playing');
  
  var playerWrapper = jQuery('#' + playerWrapperId);
  
  // prevents content beneath the player from jumping around as it is swapped
  playerWrapper.css({ height: playerWrapper.height() + 'px', visibility: 'hidden' });
  
  // making use of a generic callback that is available once the swfembed renders the player
  postSWFEmbed = function() {
    playerWrapper.css( {visibility: 'visible' });
  };
  
  new Ajax.Updater(playerWrapperId, clipUrl, { method: 'get', evalScripts: true });
};

function sign_in_css() {
	var sign_in_form = jQuery("#sign_in_form");
	var ie8accelerator = jQuery('#ie8accelerator')
	if(!sign_in_form.hasClass("form_visible")) {
		ie8accelerator.hide();
		sign_in_form.fadeIn("fast").addClass("form_visible");
		jQuery('#sign_in_form :input:visible:enabled:first').focus();
    jQuery('#sign_in_link').text('Cancel')
	}  else {	
		sign_in_form.hide().removeClass("form_visible");
    jQuery('#sign_in_link').text('Sign in')
	};
};

// Wrapper element that contains a page level clip player
playerWrapperId = 'clip_player_wrapper';





// Used on the clip and collection pages to show an advanced embed selection widget
EmbedSelector = function(initialOptions) 
{
  // html id values
  this.embedCodeId = "#embed_code";
  this.alignId = '#align';
  this.skinClass  = '.skin';
  this.advancedEmbedId = '#advanced_embed';
  this.selectedSampleId = '';
  this.busyId = '#embed_change_spinner';
  
  this.url = initialOptions.url;
  
  var self = this;
  this.debug = false;

  this.initialOptions = initialOptions;
  
  /**
   * set the initially selected player and alignment
   */
  this.initialize = function()
  {
    // add click to select on url and embed code
    add_text_select_on_click(['embed_url', 'embed_code']);
    
    // add listeners for the embed button for hover and click
    jQuery('#embed_options').click(function() {jQuery('#advanced_embed').toggleClass('visible')});
    
    jQuery(this.advancedEmbedId + ' .sample_player').bind('click', {scope: this}, this.onSampleClick);
    jQuery('#skin').change(this.onSkinChange);
    
    // set default selected player and alignment
    jQuery(this.alignId).bind('change', {scope: this}, this.onAlignChange).attr('selectedIndex', this.initialOptions.index);
    jQuery(this.skinClass).bind('change', {scope: this}, this.onSkinChange)
    jQuery('#' + this.initialOptions.player).addClass('selected');
    
      
    if(this.debug)
    {
      var embedCode = jQuery(this.embedCodeId);
      jQuery('<textarea></textarea>').attr('id', this.embedCodeId.substring(1)).attr('value', embedCode.attr('value')).
        css({'position': 'absolute', 'top': '50px', 'width': '900px', 'height': '200px'}).
        appendTo(document.body);
        
      embedCode.attr('id', '');
    }
  };
  
  this.updateCode = function()
  {
    var currentEmbed = jQuery(this.advancedEmbedId + ' .selected');
    var position = 'left';
    if(currentEmbed.hasClass('center'))
      position = 'center';
    else if(currentEmbed.hasClass('right'))
      position = 'right';
    else if(currentEmbed.hasClass('inline'))
      position = 'inline';
    
    var attrs = {'align': position, 'skin_type': currentEmbed.attr('skin_type'), 'embeddable_type': this.initialOptions.type};
    if(jQuery('#' + currentEmbed.attr('id') + '_skin_row select').attr('value'))
      attrs['flash_skin_id'] = jQuery('#' + currentEmbed.attr('id') + '_skin_row select').attr('value');
    
    console.log('will fetch new code with', attrs);
    
    jQuery(this.busyId).show();
    jQuery.get(this.url, attrs, this.onCodeUpdated);
  };
  
  /**
   * updates the alignment select with new option tags
   */
  this.updateAlignSelect = function(options)
  {
    var alignSelect = jQuery(this.alignId).html('');
    
    for(var i=0; i<options.length; ++i)
      alignSelect.append(jQuery("<option></option>").attr('value', options[i]).html(options[i]));
    
    alignSelect.attr('selectedIndex', 0);
  };
  
  this.onSampleClick = function(event)
  {
    var alignments = ['left', 'center', 'right', 'inline'];
    if(jQuery(this).attr('id') == 'sample_inline')
    {
      alignments = ['inline'];
    }
    
    event.data.scope.updateAlignSelect(alignments);
    event.data.scope.resetSamplePlayers(true);
    
    // make the table row visible for customization
    var id = jQuery(this).attr('id');
    
    // todo: fix this hack to make rows appear correctly
    if(jQuery.browser.msie)
      jQuery('#' + id + '_skin_row').css('display', 'block');
    else
      jQuery('#' + id + '_skin_row').css('display', 'table-row');
    
    jQuery(this).addClass('selected').addClass(jQuery(event.data.scope.alignId).attr('value'));
    event.data.scope.updateCode();
  };
  
  this.onAlignChange = function(event)
  {
    console.log('onAlignChange. this %o, event %o', this, event);
    
    jQuery(event.data.scope.advancedEmbedId + ' .selected').removeClass('left center right inline').addClass(jQuery(this).attr('value'));
    
    // this function may be triggered in a non-event context, so skip firing the code update
    if(event.data && event.data.scope)
      event.data.scope.updateCode();
  };
  
  this.onSkinChange = function(event)
  {
    event.data.scope.updateCode();
  };
  
  this.onCodeUpdated = function(responseData)
  {
    console.log('onCodeUpdated', typeof responseData);
    jQuery('#embed_change_spinner').hide();
    jQuery('#embed_code').attr('value', responseData);
  };
  
  this.resetSamplePlayers = function(alsoHideSkinSelect)
  {
    if(alsoHideSkinSelect)
      jQuery(this.advancedEmbedId + ' .embed_skin_row').css('display', 'none');
    
    jQuery(this.advancedEmbedId + ' .sample_player').removeClass('selected left center right inline');
  };
  
  jQuery(document).ready(function() { self.initialize();});
}

// From a passed string, return the friendly title name (i.e. 'foo.mp3' => 'foo')
function getTitleFromString(id, isActualValue)
{
  var match, title;
  
  if(isActualValue)
  {
    title = id;
  }
  else
  {
    if(id.charAt(0) != '#')
      id = '#' + id;
    
    title = jQuery(id).attr('value');
  }
  // remove everything before (and including) the previous forward/back slashes (as with a url or filesystem)
  if((match = title.match(/.+[\\/](.+)$/)))
    title = match[1];
  
  // remove file extension if it is a media file
  if((match = title.match(/(.+)\.(aac|aaf|ape|asf|avi|flac|flv|gif|jpg|jpeg|m4a|m4r|mov|mp3|mpeg|mpg|ogg|ogm|png|swf|wav|wma|wmv)$/)))
    title = match[1];
  
  title = title.replace(/[_]+/g, ' ');
  
  return title;
}

function createSpinner(target,size) {
  if(!size) {var size = 50;}
  jQuery(target).html('<img height="' + size + '" width="' + size + '" src="/images/spinner.gif" alt="Wait" title="Please wait" />');
};

function clearSpinner(target) {
  jQuery(target).html('');
};

// All upload forms validate against at least category. This standardizes the validation with ability to add a custom validation function
function addUploadFormSubmitListener(customValidationFunction, formId)
{
  if(!customValidationFunction)
    customValidationFunction = function(form) { return true; };
  
  var validation = function(event)
  {
    if(!jQuery('.category_id', this).attr('value'))
    {
      alert('Please select a category');
      event.stopPropagation();
      event.preventDefault();
      return false;
    }
    
    if(!customValidationFunction(this))
    {
      event.stopPropagation();
      event.preventDefault();
      return false;
    }
    
    console.log('returning true');
    return true;
  };
  
  formId = formId || 'upload_form'
  
  jQuery(document).ready(function() {
      console.log('adding form submit listener');
    jQuery('#' + formId).submit(validation);
  });
  
}

// Adds the non-standard (but FF, IE supported) onbeforeunload listener with the
// specified message
// Note: adding the unload listener more than once per page will only invoke the last message
// Note: I haven't found a way to get jQuery to work correctly with adding the listener
function addOnBeforeUnloadListener(message)
{
  var f = function(e)
  {
    var e = e || window.event;
    
    if(e)
      e.returnValue = message;
    
    return message;
  };
  
  window.onbeforeunload = f;
}

document.observe("dom:loaded", function() {
  // the element in which we will observe all clicks and capture
  // ones originating from pagination links
  var container = jQuery(document.body);
  
  jQuery('.ajax_pagination .pagination a').click(function() {
    new Ajax.Request(jQuery(this).href, { method: 'get' });
    return false;
  });
})

//used in the main search box
function clear_value (element_id, prompt){
      element = jQuery(element_id);
      if(element.val() == prompt) {
        element.val('')
        element.removeClass('gray')
      } 
    };
function set_value (element_id, prompt){
  element = jQuery(element_id);
  if(element.val() == '') {
    element.addClass('gray')
    element.val(prompt)
  } 
};


function ping_request(url)
{
  jQuery(document).ready(function() {
    // in case rails escaped part of the url
    if(url.indexOf('&amp;') != -1)
      url = url.replace(/\&amp;/, '&')
    
    jQuery.get(url);
  });
}


remoteLogger = new function() {
  /*
   If the same message is passed more than the threshold, that message will not be sent any more until it changes
  */
  var LAST_REMOTE_LOG_MESSAGE = '';
  var REMOTE_LOG_REPEATS = 0;
  var REMOTE_LOG_THRESHOLD = 3;
  
  var _type    = '';
  var _message = '';
  var _args    = null;
  
  this.INFO    = 'info';
  this.WARNING = 'warning';
  this.ERROR   = 'error';
  
  
  /**
   * type is one of 'info', 'warning', 'error'
   * args is an optional hash of arguments to pass
   */
  this.log = function(type, message, args)
  {
    try {
      _type = type;
      _message = message;
      _args = {};
      
      if(args instanceof Object && !(args instanceof Array))
      {
        for(var key in args)
        {
          if(typeof args[key] == 'number' || typeof args[key] == 'string' || typeof args[key] == 'boolean')
          {
            if(key == 'message' || key == 'type')  // prevent args from overwriting important params
              _args['param_' + key] = args[key];
            else
              _args[key] = args[key];
          }
          else
            _args[key] = "could not represent parameter with datatype: '" + typeof(args[key]) + "'";
        }
      }
      
      if(canSend())
        sendMessage();
    } catch(e)
    {
      console.error("Fatal error trying to use remoteLogger.log: " + e.message);
    }
  };
  
  sendMessage = function()
  {
    
    var flashVersion = 'swfobject not present, could not detect';
    var browser = 'uknown';
    
    if(typeof(swfobject) == 'object' && swfobject.getFlashPlayerVersion)
    {
      var version = swfobject.getFlashPlayerVersion();
      flashVersion = version.major + '.' + version.minor + '.' + version.release;
    }
    
    if(jQuery.browser.mozilla)
      browser = 'mozilla';
    else if(jQuery.browser.msie)
      browser = 'msie';
    else if(jQuery.browser.opera)
      browser = 'opera';
    else if(jQuery.browser.safari)
      browser = 'safari';
    
    browser += ' ver: ' + (jQuery.browser.version || 'unknown');
    
    var args = {
      type: _type, 
      message: _message, 
      logging: 'javascript', 
      url: document.URL || String(window.location) || '',
      flash: flashVersion,
      browser: browser
    };
    
    // merge to one object of args
    jQuery.extend(args, _args);
    
    jQuery.get(PING_URL, args);
  };
  
  serialize = function()
  {
    var output = _type + _message;
    
    for(var key in _args)
      output += key + _args[key];
    
    return output;
  };
  
  canSend = function(serialized)
  {
    var canSend = true;
    var serialized = serialize();
    
    if(serialized == LAST_REMOTE_LOG_MESSAGE)
    {
      if(REMOTE_LOG_REPEATS + 1 >= REMOTE_LOG_THRESHOLD)
      {
        canSend = false;
        console.error('cannot log this error any more times');
      }
      else
        ++REMOTE_LOG_REPEATS;
    }
    else
      REMOTE_LOG_REPEATS = 0;

    LAST_REMOTE_LOG_MESSAGE = serialized;
    
    return canSend;
  };
  
};

/*
creates too much noise in /javascript_logs
jQuery().ready(function(){
	jQuery.ajaxSetup({
		error:function(x,e){
		  var error = "Ajax failure: ";
			if(x.status == 0)
			  error += "Lost connection";
			else if(e == 'parsererror')
        error += 'Parsing JSON Request failed.';
			else if(e == 'timeout')
			  error += 'Request Time out.';
			else
        error += 'Unknow Error.';
			
      remoteLogger.log('error', error, {'responseText': x.responseText, 'status': x.status, 'requestedUrl': x.getResponseHeader('X-Etmnt-Requested-Url')});
		}
	});
});
*/


/**
 * Stuff to be run once the page is loaded. Each is wrapped in a function in case 
 * execution fails, will not prevent others from running
 */
jQuery(document).ready(function() {
  var toExecute = [
    function() {
      jQuery('#keywords_main_search_box').focus( function() {clear_value('#keywords_main_search_box','Find a Sound Bite')});
      jQuery('#keywords_main_search_box').blur( function() {set_value('#keywords_main_search_box','Find a Sound Bite')});
      jQuery('#main_search_button').click( function() { clear_value('#keywords_main_search_box','Find a Sound Bite'); jQuery('#main_search_form').submit() });
    },
    
    function() {
      // auto selects an input field on click or focus given classname 'auto_select'
      jQuery(document).click(function(event) {
        if(jQuery(event.target).hasClass('auto_select') && event.target.select)
          event.target.select();
      });
    },
  
    function() {
      // adds GA click tracking to specified elements
      jQuery('.ct_container a.ct_target').each(function (i) {
        var anchor = jQuery(this);
        var path = "/internal/" + anchor.parents('.ct_container').attr('id') + "/" + anchor.parents('.ct_container').attr('page_object_id') + "/" + anchor.attr('ct_type') + "/" + i + "/" + anchor.attr('link_object_id') + "/";
        anchor.click(function() {pageTracker._trackPageview(path)});
        });
    },
    
    function() {
      // given anchors with this attribute, will set a single time cookie
      jQuery('a[single_time]').click(function() {
        var value = jQuery(this).attr('single_time');
        if(value.indexOf('=') != -1) // ensure it's a key=value string
          add_single_time_cookie_value(value);
      })
    },
  
    function() {
      jQuery('.tracking_link').click(function () {
          var obj = jQuery(this);
          var url = '/ping/show?type=' + obj.attr('type') + '&id=' + obj.attr('id');
          console.log(url);
          new jQuery.get(url);
        });
    },
  
    function() {
      // checks for IE 8 specific abilities and that accelerator isn't installed
      if(navigator.userAgent.indexOf('MSIE 8.0') != -1 && !window.external.IsServiceInstalled(("http://" + location.host + "/domain/search_accelerator.xml"), "Listen"))
      {
        jQuery("#ie8accelerator").show();
      }
      else // remove contents of ie 8 accelerator to prevent any possibility of it being shown by other javascript
      {
        jQuery("#ie8accelerator").html('');
      }
    }
  ];
  
  for(var i=0; i<toExecute.length; ++i)
  {
    try { 
      toExecute[i](); 
    } catch(e) {
      remoteLogger.log(remoteLogger.ERROR, "failed to execute an onload function", {index: i});
    }
  }
});


function create_listeners() {
 jQuery('.auto_complete_field').each(function() {
   var terms_id = 'terms_' + jQuery(this).attr('id');
   jQuery(this).after('<div class="auto_complete" id="' + terms_id + '"></div>');
//   jQuery(this).attr('value', 'test');
   new Autocompleter.Local(jQuery(this).attr('id'),terms_id, terms, {fullSearch:false, frequency:0, minChars:1});
 })
}

var terms_loaded = false;
function load_terms()
{
  if(!terms_loaded)
  {
    jQuery.getScript("/collection/terms.js", create_listeners);
    terms_loaded = true;
  }
}

jQuery(document).ready( function () {
  jQuery('.auto_complete_field').focus( function () {
    console.log('adding');
    load_terms();
    })
})

/* SWFObject v2.1 <http://code.google.com/p/swfobject/>
	Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
	This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){if(AE[AA]!=Object.prototype[AA]){AD+='<param name="'+AA+'" value="'+AE[AA]+'" />'}}v.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AF+">"+AD+"</object>";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v<w;v++){d[v][0].detachEvent(d[v][1],d[v][2])}var t=i.length;for(var u=0;u<t;u++){X(i[u])}for(var r in h){h[r]=null}h=null;for(var q in swfobject){swfobject[q]=null}swfobject=null})}}();return{registerObject:function(u,q,t){if(!h.w3cdom||!u||!q){return }var r={};r.id=u;r.swfVersion=q;r.expressInstall=t?t:false;N[N.length]=r;W(u,false)},getObjectById:function(v){var q=null;if(h.w3cdom){var t=C(v);if(t){var u=t.getElementsByTagName(Q)[0];if(!u||(u&&typeof t.SetVariable!=b)){q=t}else{if(typeof u.SetVariable!=b){q=u}}}}return q},embedSWF:function(x,AE,AB,AD,q,w,r,z,AC){if(!h.w3cdom||!x||!AE||!AB||!AD||!q){return }AB+="";AD+="";if(c(q)){W(AE,false);var AA={};if(AC&&typeof AC===Q){for(var v in AC){if(AC[v]!=Object.prototype[v]){AA[v]=AC[v]}}}AA.data=x;AA.width=AB;AA.height=AD;var y={};if(z&&typeof z===Q){for(var u in z){if(z[u]!=Object.prototype[u]){y[u]=z[u]}}}if(r&&typeof r===Q){for(var t in r){if(r[t]!=Object.prototype[t]){if(typeof y.flashvars!=b){y.flashvars+="&"+t+"="+r[t]}else{y.flashvars=t+"="+r[t]}}}}f(function(){U(AA,y,AE);if(AA.id==AE){W(AE,true)}})}else{if(w&&!A&&c("6.0.65")&&(h.win||h.mac)){A=true;W(AE,false);f(function(){var AF={};AF.id=AF.altContentId=AE;AF.width=AB;AF.height=AD;AF.expressInstall=w;k(AF)})}}},getFlashPlayerVersion:function(){return{major:h.pv[0],minor:h.pv[1],release:h.pv[2]}},hasFlashPlayerVersion:c,createSWF:function(t,r,q){if(h.w3cdom){return U(t,r,q)}else{return undefined}},removeSWF:function(q){if(h.w3cdom){X(q)}},createCSS:function(r,q){if(h.w3cdom){V(r,q)}},addDomLoadEvent:f,addLoadEvent:R,getQueryParamValue:function(v){var u=K.location.search||K.location.hash;if(v==null){return g(u)}if(u){var t=u.substring(1).split("&");for(var r=0;r<t.length;r++){if(t[r].substring(0,t[r].indexOf("="))==v){return g(t[r].substring((t[r].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(A&&M){var q=C(m);if(q){q.parentNode.replaceChild(M,q);if(l){W(l,true);if(h.ie&&h.win){M.style.display="block"}}M=null;l=null;A=false}}}}}();