
if (!referrals) { var referrals = {}; }

referrals._urlMakers = {
    'compare': function (tab, target) { 
              	    return '/referrals/compare/' + tab + '/' + target + '/'; },
    'site' : function (tab, target) { 
              	    return '/referrals/' + tab + '/' + target + '/'; },
    'category' : function (tab, target) {
                    return '/referrals/' + tab + '/' + target + '/'; }
};

referrals.submit_form = function() {
  /* Handles the referral analytics submission form for the entire app (i.e.
    all the forms for all the report types)
  */
  var form_id = $j(this).attr('id');
  
  var report_type = $j("form#" + form_id + " input[name='t']").attr('value');
  
  var site1 = $j("form#" + form_id + " input[name='s1']").attr('value');
  var site2 = $j("form#" + form_id + " input[name='s2']").attr('value');
  
  // if we only get site2, then put it into site1
  if ((!site1 || site1.slice(0, 4) == 'e.g.') && 
     !(!site2 || site2.slice(0, 4) == 'e.g.')) {
    site1 = site2;
    site2 = undefined;
  }
  
  // form is empty
  if (!site1 || site1.slice(0, 4) == 'e.g.') {
    return false;
  }
  
  // set the loading background
  $j("form#" + form_id + " input:first").addClass('loading')
  
  // overwrite the report type based on the value of site2
  if (!site2 || site2.slice(0, 4) == 'e.g.') {
    site2 = '';
    if (report_type == 'referrals_comp_refs') {report_type = 'referrals_referrals';}
    if (report_type == 'referrals_comp_dests') {report_type = 'referrals_destinations';}
  }
  else {
    if (report_type == 'referrals_referrals') {report_type = 'referrals_comp_refs';}
    if (report_type == 'referrals_destinations') {report_type = 'referrals_comp_dests';}
  }

  // form is good, do your magic
  var form = $j('form#' + form_id);
  var params = {'t': report_type, 's1': site1, 's2': site2};
  // use form values to make up a url /_search/ will like
  $j.ajax({'url': form.attr('action'),
           'data': $j.param(params), 
           'success': function(data) {
             $j("form#" + form_id + " input:first").removeClass('loading');
             _search_success_callback(data);
            }
  });
  return false;
};

referrals.tab_selected_handler = function(event) {
  /*
   * Handles the selection of a tab. This function will generate and redirect
   * to the correct URL.
   *
   */
  var url = referrals._urlMakers[event.data.mode](event.data.tab, event.data.target);
  window.location = url;
};

referrals.report_data_url = function (report_type, target) {
  /*
   * Return the URL of the datasource for a particular report.
   */
  return '/referrals/sites/' + report_type + '/' + target + '/';
};

referrals.initialize_grid = function(data_url) {
  /*
   * Initialize the grid widget.  (Gridget?)
   */
  dhtmlxError.catchError("ALL", referrals.grid._error_handler);
  
  xgrid = new dhtmlXGridObject('grid-container');
  // row height needs to be set if it isn't the default
  xgrid.setAwaitedRowHeight(27);
  xgrid.setImagePath('/site_media/xgrid/imgs/');
  xgrid.enableTooltips('false');
  xgrid.attachEvent('onRowCreated', referrals.grid._row_created_handler);
  xgrid.attachEvent('onBeforeSorting', referrals.grid._make_sort_handler(data_url));
  xgrid.attachEvent('onXLS', referrals.grid._request_handler);
  xgrid.attachEvent('onXLE', referrals.grid._ready_handler);
  
  xgrid.loadXML(data_url);
}

/*
 * Spinner management object.  Binds two callbacks: One is on the
 * export element, which gets triggered when the link is clicked,
 * causing that element to get replaced with the spinner text.
 * The other is on the window so that when focus returns to it
 * (ie. after a successful csv download) it checks if the spinner
 * is "spinning" and tells it to return the spinner text to 
 * normal once again.
 *
 * Notes:
 *   - This is a proper JavaScript constructor, therefore you have
 *     to call it with the new keyword, eg:
 *         new CSVSpinner({'data_url': some_url_here});
 *   - One of these objects should be initialized per export link
 *     on the page.
 *   - We only bind the window.onfocus callback once (per CSVSpinner
 *     object).  If it's called and we're not spinning we do nothing.
 *   - In contrast, the dom elements representing the spinner link
 *     get clobbered and replaced each time we reset the innerHTML
 *     of the span.  Consequently, we have to rebind an event handler
 *     to the link each time it is reset.
 */
referrals.CSVSpinner = function (opts) {
    var defaults = {
        'data_url': 'REQUIRED',
        'export_selector': 'a#csv-export'
    };
    $j.params(this, defaults, opts || {});

    // Since our callbacks are going to get assigned a lot,
    // just bind them locally, once.
    $j.bindMethods(this, 'start_spinner', 'stop_spinner');
    
    this._spinning = false;
    this._disabled = false;
    this._inner_html = $j(this.export_selector).parent().html();
    
    $j(this.export_selector).click(this.start_spinner);
    $j(window).focus(this.stop_spinner);
};

referrals.CSVSpinner.prototype.start_spinner = function () {
    var export_span = $j(this.export_selector);
    if (! (export_span.hasClass('grayed_out') || this._disabled)) {
        $j(export_span).replaceWith('<span id="export-wait">Exporting CSV</span>');
    }
    this._spinning = true;
    return ! this._disabled;
};

referrals.CSVSpinner.prototype.stop_spinner = function () {
    if (this._spinning) {
        $j('span#export-wait').replaceWith(this._inner_html); 
        $j(this.export_selector).click(this.start_spinner);
        this._spinning = false;
    }
    return true;
};

referrals.CSVSpinner.prototype.disable = function () {
    this._disabled = true;
    $j(this.export_selector).addClass('grayed-out');
    $j(this.export_selector + ' > div.img').hide();
};

referrals.CSVSpinner.prototype.enable = function () {
    this._disabled = false;
    $j(this.export_selector).removeClass('grayed-out');
    $j(this.export_selector + ' > div.img').show();
};



referrals.site_compare_handler = function(event) {
  /*
   * Handles the display of an additional input box if the user wants to
   * "compare" to another site.
   *
   */
  var inputobj = $j('<input type="text" name="s2" value="e.g. amazon.com" />');
  $j(this).replaceWith(inputobj);
  inputobj.bind('focus', utils.handle_input_focus);
  inputobj.bind('blur', referrals.input_blur_handler);
  inputobj.focus();
};

referrals.input_blur_handler = function(event) {
  /*
   * Handles the blur event from an input box and displays default text
   *
   */
  var def_text = ($j(this)[0].name == 's1') ? 'e.g. compete.com' : 'e.g. amazon.com';
  
  if ($j(this).attr('value') == '') {
    $j(this).addClass('virgin').attr('value', def_text);
  } else {
    $j(this).removeClass('virgin');
  }
};

//
// landing page functions here

referrals.initialize_landing_page = function() {  
  // the category dropdowns
  cat_dropdown.initialize('referrals-category', true);
  cat_dropdown.initialize('destinations-category', true);
  
  // all the input handlers
  $j('input').addClass('virgin')
  $j('input').click(function() {$j(this).removeClass('virgin')})
  $j('input').bind('blur', referrals.input_blur_handler)
  
  // the referrals tab selectors
  $j('li.selector').click(function() {
    var link_name = $j(this).attr('id').split('-')[1]; // i.e. referrals_comp_refs
    // grab a section_name (i.e. referrals), and a tab_name (i.e. comp_refs)
    var _ = link_name.split('_')
    var section_name = _[0]
    var tab_name = _.slice(1).join('_')
    referrals.select_tab(section_name, tab_name)
  });
  
  // the forms
  $j('form:not(.category)').submit(referrals.submit_form);
  $j("form.category").submit(referrals.submit_category_form);
}

referrals.select_tab = function(section_name, tab_name) {
  /* Binded to the site/category/compare links on the landing page
  section_name is referrals/destinations
  tab_name is referrals/destinations, category, comp_refs/comp_dests
  */
  
  // hide all other blocks and remove .selected as appropriate
  $j('#' + section_name + ' > ul li.selected').removeClass('selected')
  $j('form.' + section_name).hide()
  
  // show tab_name's block, and mark as selected
  $j('#link-' + section_name + '_' + tab_name).addClass('selected')
  $j('form#' + section_name + '_' + tab_name).show()
  
  return false;
}

referrals.submit_category_form = function() {
  /* binded to the category forms (both refs and dests) on the landing page
  */
  
  // the stem of the url comes as a hidden value
  var url = $j("form#" + this.id + " input[name='t']").attr('value')
  // the category id
  var cat_id = cat_dropdown.get_category_id(this.id.replace('_', '-'))
  
  if (cat_id) {window.location = '/referrals/' + url + '/' + cat_id + '/';}
  return false;
}

//
// grid related functions begin here

referrals.grid = {};
referrals.grid._last_load_id = '';

referrals.grid._row_created_handler = function(id, row, xml) {
  /* Event handler called by the grid whenever a new row is added to the grid 
  */   
  if (sitecol) {
    var sitecell = xgrid.cellById(id, sitecol);
    var site = $j(sitecell.getValue());
    site.hover(siteHover, siteUnHover);
    $j(sitecell.cell).empty().append(site);
  }
  var rankcell = xgrid.cellById(id,0);
  $j(rankcell.cell).empty().append( Number(id) + 1 );
};

referrals.grid._reverse_sort_direction = function(direct) {
  var directions_list = {'asc':'des', 'des':'asc'};
  return directions_list[direct];
}

// Use a closure so we can state trap the URL we want to direct to.
referrals.grid._make_sort_handler = function (url) {
  return function(col_index, _useless_parameter_here, direct) {
    /* Server side sort for the grid.  It (ab)uses some global
     * variables set up by the template
     * referrals/templates/base.html
     */
    referrals.grid._last_load_id = ''; // used by _grid_request_handler
  
    if (window.IS_TEASER || popup_help.HELP_OPEN || BLOCKED_ROWS[col_index] ) {
      return;
    }
  
    // do not allow sorting by Rank (the first column)
    if (col_index == 0) { return false; }
    if ( REVERSING_ROWS[col_index] ){
      direct = referrals.grid._reverse_sort_direction(direct);
      for (key in REVERSING_ROWS) {
        REVERSING_ROWS[key] = true;
      }
      REVERSING_ROWS[col_index] = false;
    }
    
    $j('div#rcontent-wait').show()
    xgrid.clearAll();
    xgrid.loadXML(url + (url.indexOf('?') >= 0 ? '&' : '?') + 
                  'sort_by=' + col_index + '&sort_order=' + direct);
    xgrid.setSortImgState(true, col_index, direct);
  };
};

referrals.grid._request_handler = function(grid) {
  /* This will prevent the grid from going spastic if it doesn't get the
     exact data it's expecting. 
     _last_load_id gets resetted by _grid_sort_handler
  */
  if (typeof(grid._current_load) == 'undefined') {
    return false;
  }
  var _ = grid._current_load[0] + '__' + grid.rowsBuffer.length;
  if (_ == referrals.grid._last_load_id) {
    throw 'already scrolled';
  }
  referrals.grid._last_load_id = _;
}

referrals.grid._ready_handler = function(grid, rowcount) {
  $j('div#rcontent-wait').hide();
}

referrals.grid._error_handler = function(type, desc, error_data) {
  return false;
}

// catch (in an admitedly hacky way), the scrolling exception
// window.onerror = function(message, uri, line) {
//   return (message != 'already scrolled');
// }

/* For the report loading pop-up */
referrals.inititialize_loading_dialog = function(){
  var loading_dialog = $j('#loading_dialog').dialog({ 
    bgiframe:true,
    autoOpen:true,
    draggable:false,
    modal:true,
    resizable:false,
    width:450,
    height:230,
    zIndex:'9999',
    open: function() {$j(this).focus()},
    close: function() {loading_dialog.open()},
    dialogClass: 'loading_dialog'
  });
  $j.ajax({
    type: "GET",
    url: referrals.ajax_url,
    data: "",
    success: function(msg){
      window.location.replace(referrals.ajax_url);
    },
    error: function(request, error){
      loading_dialog.html(referrals.loading_dialog_error_text);
    }
  });
}
