var BOTS4 = {}; // Legacy.
var bots4 = {}; // New.

BOTS4.init = function () {
    BOTS4.pageTitle.init();
    BOTS4.sidebar.init();
    BOTS4.buffs.init();
};

BOTS4.buffs = {

    init: function () {
        jQuery('.buff').each(function () {
            var id;

            id = jQuery(this).attr('id');
            id = id.substring(id.indexOf('-') + 1);

            jQuery('#buff-' + id + '-pause').click(
                function () {
                    var id;

                    id = jQuery(this).attr('id');
                    id = id.substring(id.indexOf('-') + 1);
                    id = id.substring(0, id.indexOf('-'));

                    jQuery.ajax('/ajax/buff-modify.php?action=pause&id=' + id);

                    jQuery('#buff-' + id + '-pause').hide();
                    jQuery('#buff-' + id + '-resume').show();
                    jQuery('#buff-' + id).addClass('buff-inactive');

                    jQuery('#buff-' + id).trigger('mouseleave');
                }
            );

            jQuery('#buff-' + id + '-resume').click(
                function () {
                    var id;

                    id = jQuery(this).attr('id');
                    id = id.substring(id.indexOf('-') + 1);
                    id = id.substring(0, id.indexOf('-'));

                    jQuery.ajax('/ajax/buff-modify.php?action=resume&id=' + id);

                    jQuery('#buff-' + id + '-resume').hide();
                    jQuery('#buff-' + id + '-pause').show();
                    jQuery('#buff-' + id).removeClass('buff-inactive');

                    jQuery('#buff-' + id).trigger('mouseleave');
                }
            );

            jQuery('#buff-' + id + '-cancel').click(
                function () {
                    var id;

                    id = jQuery(this).attr('id');
                    id = id.substring(id.indexOf('-') + 1);
                    id = id.substring(0, id.indexOf('-'));

                    if (!confirm('Cancel buff? There\'s no downside to just pausing it unless you\'re really intent on removing it.')) {
                        return;
                    }

                    jQuery.ajax('/ajax/buff-modify.php?action=cancel&id=' + id);

                    jQuery('#buff-' + id).fadeOut();
                }
            );

            // hover effect
            jQuery(this).hover(
                function () {
                    var id;

                    id = jQuery(this).attr('id');
                    id = id.substring(id.indexOf('-') + 1);
                    jQuery('#buff-' + id + '-details').stop(false, true).slideDown(100);
                },
                function () {
                    var id;

                    id = jQuery(this).attr('id');
                    id = id.substring(id.indexOf('-') + 1);
                    jQuery('#buff-' + id + '-details').stop(false, true).slideUp(100);
                }
            );
        });

        jQuery('.buff-pulse').each(function () {
            jQuery(this).pulse({
                opacity: [0, 1]
            }, 500, 99999999);
        });
    }

};

BOTS4.settings = {

    mobileFloatingSidebar: undefined,
    mobileShowroomScrollbars: undefined,

    init: function (settings) {
        this.mobileFloatingSidebar = settings.mobileFloatingSidebar;
        this.mobileShowroomScrollbars = settings.mobileShowroomScrollbars;
    },

    hasMobileFloatingSidebar: function () {
        return this.mobileFloatingSidebar;
    },

    hasMobileShowroomScrollbars: function () {
        return this.mobileShowroomScrollbars;
    }

};

BOTS4.sidebar = {

    sidebar: undefined,
    sidebarProto: undefined,
    startPosition: 0,

    init: function () {
        if (!BOTS4.settings.hasMobileFloatingSidebar()) {
            return;
        }

        this.sidebar = jQuery('#left-nav');
        this.sidebarProto = $('left-nav');
        this.startPosition = this.sidebarProto.cumulativeOffset().top;

        this.sidebarProto.setStyle({
            position: 'relative'
        });

        jQuery(window)
            .scroll(this.tryToMove.bind(this))
            .resize(this.tryToMove.bind(this));
    },

    tryToMove: function () {
        if (this.isLargeEnough()) {
            this.sidebar.stop();
            this.move();
        } else {
            this.reset();
        }
    },

    isLargeEnough: function () {
        return document.viewport.getHeight() > this.getRequiredHeight();
    },

    getRequiredHeight: function () {
        return this.startPosition + this.sidebarProto.getHeight();
    },

    move: function () {
        this.sidebar.stop().animate({
            top: '+=' + (this.startPosition - this.sidebarProto.viewportOffset().top) + 'px'
        }, 500);
    },

    reset: function () {
        this.sidebarProto.setStyle({
            top: '0px'
        });
    }

};

BOTS4.pageTitle = {

    init: function () {
        var title = jQuery('#page-title');

        // make sure title exists
        if (!title) {
            return;
        }

        var protoTitle = $('page-title');
        var position = document.viewport.getWidth() - protoTitle.cumulativeOffset().left - protoTitle.getWidth();
        title.css('left', position + 'px');

        setTimeout(function () {
            title.css('visibility', 'visible');
            title.hide();
            title.animate({
                left: '-=' + position
            }, {duration: 1000, queue: false});
            title.fadeIn(1500);
        }, 100);
    }

};

BOTS4.notifications = {

    init: function (trophies) {
        var i;
        var html = '';

        html += '<div id="notifications">';
        for (i = 0; i < trophies.length; i++) {
            html += '<div style="display: none;" class="notification notification-' + trophies[i].grade + '">';
            html += 'Trophy Unlocked! ';
            html += '<img src="/images/trophies/' + trophies[i].grade + '-small.png" width="17" height="17" alt="" /> ';
            html += '<a href="/trophies/' + trophies[i].id + '">' + trophies[i].name + '</a>';
            html += '<div class="subtext" style="float: right; padding: 3px;">(click to dismiss)</div>';
            html += '</div>'
        }
        html += '</div>';

        jQuery(document.body).prepend(html);
        jQuery('.notification').each(function (i) {
            var that = this;
            setTimeout(function () {
                jQuery(that).fadeIn(1000);
            }, 500);
            jQuery(this).click(function () {
                jQuery.ajax('/ajax/notification-dismiss.php?id=' + trophies[i].id);
                jQuery(this).slideUp();
            });
        });
    }
};

BOTS4.util = {

    commas: function (nStr) {
        var x;
        var x1;
        var x2;
        var rgx;

        nStr += '';
        x = nStr.split('.');
        x1 = x[0];
        x2 = x.length > 1 ? '.' + x[1] : '';
        rgx = /(\d+)(\d{3})/;
        while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + ',' + '$2');
        }
        return x1 + x2;
    },

    post: function (path, params) {
        var form = document.createElement('form');
        var key;
        var hiddenField;

        form.setAttribute('method', 'post');
        form.setAttribute('action', path);

        for (key in params) {
            hiddenField = document.createElement('input');
            hiddenField.setAttribute('type', 'hidden');
            hiddenField.setAttribute('name', key);
            hiddenField.setAttribute('value', params[key]);

            form.appendChild(hiddenField);
        }

        document.body.appendChild(form);
        form.submit();
    },

    singular: function (value, singular, plural) {
        if (plural === undefined) {
            if (value !== 1) {
                return singular + 's';
            } else {
                return singular;
            }
        } else {
            if (value !== 1) {
                return plural;
            } else {
                return singular;
            }
        }
    }

};

bots4.util = function() {};

/**
 * Adds commas to a number.
 */
bots4.util.commas = function(nStr) {
  nStr += '';
  var x = nStr.split('.');
  var x1 = x[0];
  var x2 = x.length > 1 ? '.' + x[1] : '';
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(x1)) {
      x1 = x1.replace(rgx, '$1' + ',' + '$2');
  }
  return x1 + x2;
};

/**
 * Converts a name to its canonical form to be used in urls.
 */
bots4.util.canonical = function(name) {
  return name.replace(/ /g, '-');
};

/**
 * Gets the level corresponding to the ratio for formatting.
 */
bots4.util.ratioLevel = function(ratio) {
  ratio = ratio.toFixed(2);
  if (ratio <= 0.3) {
    return 1;
  } else if (ratio <= 0.5) {
    return 2;
  } else if (ratio <= 0.7) {
    return 3;
  } else if (ratio <= 0.9) {
    return 4;
  } else if (ratio <= 1.1) {
    return 5;
  } else if (ratio <= 1.3) {
    return 6;
  } else if (ratio <= 1.5) {
    return 7;
  } else if (ratio <= 1.7) {
    return 8;
  } else if (ratio <= 1.9) {
    return 9;
  } else if (ratio <= 2.1) {
    return 10;
  } else if (ratio <= 2.3) {
    return 11;
  } else if (ratio <= 2.5) {
    return 12;
  } else if (ratio <= 2.7) {
    return 13;
  } else if (ratio = 3.0) {
    return 14;
  } else {
    return 15;
  }
};

bots4.util.TableSorter = function(table, rows) {
  this.table_ = table;

  // Initialize internal data structure.
  this.rows_ = [];
  for (var i = 0; i < rows.length; i++) {
    var row = rows[i];

    this.rows_.push({elt: row, sorts: []});
  }

  this.arrow_ = jQuery('<span>', {'class': 'TABLESORTER_ARROW'});
};

bots4.util.TableSorter.SORTABLE_CLASS_ = 'TABLESORTER_SORTABLE';
bots4.util.TableSorter.SORTABLE_HOVER_CLASS_ = 'TABLESORTER_SORTABLE_HOVER';
bots4.util.TableSorter.LABEL_CLASS_ = 'TABLESORTER_LABEL';

bots4.util.TableSorter.ARROW_ASC_ = '\u2191';
bots4.util.TableSorter.ARROW_DESC_ = '\u2193';

bots4.util.TableSorter.prototype.nextSortId_ = 0;
bots4.util.TableSorter.prototype.lastSortIdClicked = null;

bots4.util.TableSorter.prototype.addSort = function(header, values, opt_f) {
  // Augment internal data structure with new values.
  for (var i = 0; i < this.rows_.length; i++) {
    var row = this.rows_[i];

    row.sorts.push(values[i]);
  }

  header.addClass(bots4.util.TableSorter.SORTABLE_CLASS_);

  // Wrap the label inside a new span so only it (not the arrow) gets the hover
  // effect for underline.
  header.html(jQuery('<span>', {
    'class': bots4.util.TableSorter.LABEL_CLASS_,
    text: header.text()
  }));

  if (opt_f) {
    var f = function(id, a, b) {
      return opt_f(a.sorts[id], b.sorts[id]);
    }.bind(this, this.nextSortId_);
  } else {
    var f = function(id, a, b) {
      return b.sorts[id] - a.sorts[id];
    }.bind(this, this.nextSortId_);
  }

  // Attach listeners
  header.hover(function(event) {
    jQuery(this).addClass(bots4.util.TableSorter.SORTABLE_HOVER_CLASS_);
  }, function(event) {
    jQuery(this).removeClass(bots4.util.TableSorter.SORTABLE_HOVER_CLASS_);
  });
  header.click(this.headerClicked_.bind(this, this.nextSortId_, f));

  this.nextSortId_++;
};

bots4.util.TableSorter.prototype.headerClicked_ = function(id, f, event) {
  var sortDesc = true;
  if (id == this.lastSortIdClicked_) {
    sortDesc = false;
    this.lastSortIdClicked_ = null;
  } else {
    this.lastSortIdClicked_ = id;
  }

  if (sortDesc) {
    this.arrow_.html(bots4.util.TableSorter.ARROW_DESC_);
  } else {
    this.arrow_.html(bots4.util.TableSorter.ARROW_ASC_);
  }

  var header = jQuery(event.currentTarget);
  header.append(this.arrow_);

  this.sort_(f, sortDesc);
};

bots4.util.TableSorter.prototype.sort_ = function(f, sortDesc) {
  this.rows_.sort(f);
  if (sortDesc) {
    for (var i = 0; i < this.rows_.length; i++) {
      var row = this.rows_[i];
      row.elt.appendTo(this.table_);
    }
  } else {
    for (var i = this.rows_.length - 1; i >= 0; i--) {
      var row = this.rows_[i];
      row.elt.appendTo(this.table_);
    }
  }
};

bots4.util.Date = function(opt_date) {
  if (opt_date) {
    this.date_ = opt_date;
  } else {
    this.date_ = new Date();
  }
};

bots4.util.Date.prototype.date_;

bots4.util.Date.fromUnixTimestamp = function(unixTimestamp) {
  return new bots4.util.Date(new Date(unixTimestamp * 1000));
};

bots4.util.Date.prototype.getTime = function() {
  return this.date_.getTime();
};

bots4.util.Date.prototype.toString = function() {
  var year = this.date_.getFullYear();
  var month = this.date_.getMonth() + 1;
  var day = this.date_.getDate();
  var hour = this.date_.getHours();
  var minutes = this.date_.getMinutes();
  var seconds = this.date_.getSeconds();

  var sb = [];

  sb.push(year);
  sb.push('-');
  sb.push(month < 10 ? '0' + month : month);
  sb.push('-');
  sb.push(day < 10 ? '0' + day : day);
  sb.push(' ');
  sb.push(hour < 10 ? '0' + hour : hour);
  sb.push(':');
  sb.push(minutes < 10 ? '0' + minutes : minutes);
  sb.push(':');
  sb.push(seconds < 10 ? '0' + seconds : seconds);

  return sb.join('');
};

bots4.util.Date.prototype.ago = function(now) {
  var seconds = Math.round((now.getTime() - this.date_.getTime()) / 1000);

  if (seconds < 60) {
    return seconds + ' ' + bots4.util.Grammar.plural(seconds, 'second');
  }

  var minutes = Math.floor(seconds / 60);
  if (minutes < 60) {
    return minutes + ' ' + bots4.util.Grammar.plural(minutes, 'minute');
  }

  var hours = Math.floor(minutes / 60);
  if (hours < 48) {
    return hours + ' ' + bots4.util.Grammar.plural(hours, 'hour');
  }

  var days = Math.floor(hours / 24);
  return days + ' ' + bots4.util.Grammar.plural(days, 'day');
};

bots4.util.Grammar = {};

bots4.util.Grammar.plural = function(value, singular, opt_plural) {
  if (!opt_plural) {
    if (value != 1) {
      return singular + 's';
    } else {
      return singular;
    }
  } else {
    if (value != 1) {
      return opt_plural;
    } else {
      return singular;
    }
  }
};

