Forum = (function() {
var construct;
construct = function(options) {
this.default_options = options;
this.restore_and_restart();
};
construct.prototype.initialize_display = function(space, plot_space) {
this.canvas = $(space).get(0);
this.context = this.canvas.getContext("2d");
this.plot_space = $(plot_space);
this.spacing = ABF.SPACING;
this.plot = ABF.SELECTED_PLOT;
this.replot();
this.draw();
};
construct.prototype.restore_and_restart = function() {
this.options = {};
this.set_options(this.default_options);
this.restart();
};
construct.prototype.restart = function() {
var id,
i,
j,
seed_thread,
seed_single,
init_array = [];
this.actors = [];
this.actors_id_counter = 0;
this.posts_id_counter = 0;
this.run_count = 0;
this.users_count = 0;
this.users_per_topic_count = [];
this.daily_arrivals_remainder = 0;
this.threads_count = 0;
this.reset_daily_counts();
if (this.options.with_thresholds) {
this.critical_mass_days = -1;
this.locked = false;
}
this.plot_users = [];
this.plot_daily_unique_posters = [];
this.plot_daily_arrivals = [];
this.plot_daily_leavers = [];
this.plot_posts = [];
this.plot_threads = [];
this.plot_topics = [];
for (i = 0; i < 4; i++) {
this.plot_topics[i] = [];
}
this.positions_hash = {};
this.threads = [];
seed_thread = [
{indent: 0},
{indent: 1},
{indent: 2},
{indent: 2},
{indent: 2},
{indent: 3},
{indent: 3},
{indent: 3},
{indent: 1},
{indent: 2},
{indent: 2},
{indent: 2},
{indent: 3},
{indent: 3},
{indent: 3}
];
seed_single = [seed_thread[0]];
if (this.options.initial_threads < 1) {
init_array.push(seed_single);
} else {
for (i = 0; i < this.options.initial_threads; i++) {
init_array.push(seed_thread);
}
}
if (this.options.mode == ABF.MODES.random) {
new_array = [];
for (i = 0; i < init_array.length; i++) {
for (j = 0; j < init_array[i].length; j++) {
init_array[i][j].indent = 0;
new_array.push([init_array[i][j]]);
}
}
init_array = new_array;
} else if (this.options.mode == ABF.MODES.threaded) {
for (i = 0; i < init_array.length; i++) {
for (j = 0; j < init_array[i].length; j++) {
if (init_array[i][j].indent !== 0) {
init_array[i][j].indent = j;
}
}
}
}
this.append_threads(init_array);
this.reset_daily_counts();
for (i = 0; i < this.options.initial_actors; i++) {
this.actors.push(new Actor({}, this));
}
this.prune_actors_and_add_to_posts();
if (this.canvas) {
this.draw();
this.replot();
}
};
construct.prototype.run = function() {
var new_visitors,
changed_positions = false,
i;
if (!this.options.with_thresholds || !this.locked) {
for (i = 0; i < this.actors.length; i++) {
this.actors[i].run();
if (this.actors[i].left_forum) {
this.actors.splice(i, 1);
this.daily_leavers_count++;
i--;
}
}
if (this.options.mode != ABF.MODES.random) {
this.prune_threads();
changed_positions = true;
}
if (this.options.mode == ABF.MODES.ordered) {
this.reorder_threads();
changed_positions = true;
}
if (changed_positions) {
this.redo_positions_hash();
}
if (this.run_count % 240 === 0) {
this.add_actors();
}
this.prune_actors_and_add_to_posts();
}
this.run_plot_data();
if (this.canvas) {
this.draw();
this.draw_plot();
}
this.run_count += 1;
};
construct.prototype.set_mode = function(selector) {
var key = selector.selectedIndex,
previous_mode = this.options.mode;
this.options.mode = key;
if (previous_mode != this.options.mode && (previous_mode == ABF.MODES.random || this.options.mode == ABF.MODES.random)) {
this.toggleOrder();
}
this.restart();
};
construct.prototype.set_plot = function(selector) {
var key = selector.selectedIndex;
this.plot = key;
this.replot();
};
construct.prototype.toggleOrder = function() {
if (this.options.direction == ABF.DIRECTIONS.oldnew) {
this.options.direction = ABF.DIRECTIONS.newold;
} else {
this.options.direction = ABF.DIRECTIONS.oldnew;
}
this.restart();
};
construct.prototype.toggleRun = function() {
if (!this.running) {
this.running = true;
this.timeout = setInterval("forum.run()", 5);
} else {
this.running = false;
clearInterval(this.timeout);
}
};
construct.prototype.append_threads = function(thread_arrays) {
for (var i = 0; i < thread_arrays.length; i++) {
this.append_thread(thread_arrays[i]);
}
};
construct.prototype.append_thread = function(thread_array) {
var insert_position = this.threads.length;
this.threads[insert_position] =
new ForumThread(thread_array, insert_position, this);
return this.threads[insert_position];
};
construct.prototype.add_actors = function() {
var i;
if (this.options.with_thresholds) {
for (i = 0; i < this.options.daily_arrivals; i++) {
this.actors.push(new Actor({}, this));
}
if (this.critical_mass_days == -1 && this.daily_unique_posters_count > this.options.threshold_average) {
this.critical_mass_days = (this.run_count * 1.0) / 240;
this.locked = true;
}
} else if (this.run_count > 1) {
this.daily_arrivals_remainder = this.daily_arrivals_remainder +
this.daily_unique_posters_count * this.options.daily_arrivals_fraction;
for (i = 0; i < this.daily_arrivals_remainder; i++) {
this.actors.push(new Actor({}, this));
this.daily_arrivals_count++;
}
this.daily_arrivals_remainder = this.daily_arrivals_remainder - this.daily_arrivals_count;
}
};
construct.prototype.prune_threads = function() {
var nr_to_remove,
i,
property;
if (this.threads.length > this.options.max_threads) {
nr_to_remove = this.threads.length - this.options.max_threads;
for (i = 0; i < nr_to_remove; i++) {
this.threads[i].delete_posts();
}
this.threads.splice(0, nr_to_remove);
}
};
construct.prototype.reorder_threads = function() {
for (i = 0; i < this.threads.length; i++) {
this.threads[i].reweight_thread_and_posts(this.run_count);
this.threads[i].reorder_posts();
}
this.threads.sort(ABF.sort_by_first_posts_weight);
};
construct.prototype.redo_positions_hash = function() {
var position_hash,
i,
j;
for (i = 0; i < this.threads.length; i++) {
for (j = 0; j < this.threads[i].posts.length; j++) {
position_hash = this.positions_hash[this.threads[i].posts[j].id];
position_hash.thread = i;
position_hash.post = j;
}
}
};
construct.prototype.prune_actors_and_add_to_posts = function() {
var position_hash,
i;
if (this.options.with_thresholds) {
for (i = 0; i < this.actors.length; i++) {
if (this.actors[i].threshold > this.daily_unique_posters_count) {
this.actors[i].leave_forum();
}
}
}
for (i = 0; i < this.actors.length; i++) {
if (this.actors[i].position !== false) {
position_hash = this.positions_hash[this.actors[i].position];
if (position_hash !== undefined) {
this.threads[position_hash.thread].posts[position_hash.post].actor = this.actors[i];
} else {
this.actors[i].drop_off_page();
}
}
}
};
construct.prototype.draw = function() {
this.canvas.width = this.canvas.width;
if (this.options.direction == ABF.DIRECTIONS.oldnew) {
for (i = 0; i < this.threads.length; i++) {
this.threads[i].draw(i);
}
} else {
for (i = this.threads.length - 1; i >= 0; i--) {
this.threads[i].draw(this.threads.length - 1 - i);
}
}
};
construct.prototype.replot = function() {
var plot_options = {
series: { shadowSize: 0 },
xaxis: { show: false }
};
this.plotter = $.plot(this.plot_space, [], plot_options);
this.run_plot_data();
this.draw_plot();
};
construct.prototype.run_plot_data = function() {
this.plot_posts.push([this.run_count, this.posts_id_counter]);
this.plot_users.push([this.run_count, this.users_count]);
this.plot_threads.push([this.run_count, this.threads_count]);
for (i = 0; i < 4; i++) {
this.plot_topics[i].push([this.run_count, this.users_per_topic_count[i]]);
}
if (this.run_count % 240 === 0) {
this.plot_daily_unique_posters.push([this.run_count, this.daily_unique_posters_count]);
this.plot_daily_arrivals.push([this.run_count, this.daily_arrivals_count]);
this.plot_daily_leavers.push([this.run_count, this.daily_leavers_count]);
this.reset_daily_counts();
}
};
construct.prototype.draw_plot = function() {
if (this.plot == ABF.PLOTS.unique_posters) {
this.plotter.setData([this.plot_daily_unique_posters]);
} else if (this.plot == ABF.PLOTS.users) {
this.plotter.setData([this.plot_users]);
} else if (this.plot == ABF.PLOTS.arrivals_leavers) {
this.plotter.setData([this.plot_daily_arrivals, this.plot_daily_leavers]);
} else if (this.plot == ABF.PLOTS.posts) {
this.plotter.setData([this.plot_posts]);
} else if (this.plot == ABF.PLOTS.threads) {
this.plotter.setData([this.plot_threads]);
} else if (this.plot == ABF.PLOTS.topics) {
this.plotter.setData(this.plot_topics);
}
this.plotter.setupGrid();
this.plotter.draw();
};
construct.prototype.data = function() {
return {
config: this.options,
data: {
unique_posters: [this.plot_daily_unique_posters],
users: [this.plot_users],
arrivals_leavers: [this.plot_daily_arrivals, this.plot_daily_leavers],
posts: [this.plot_posts],
threads: [this.plot_threads],
topics: this.plot_topics,
critical_mass_days: this.critical_mass_days
}};
};
construct.prototype.reset_daily_counts = function() {
if (!this.options.with_thresholds || !this.locked) {
this.daily_unique_posters_count = 0;
this.daily_unique_posters_hash = {};
this.daily_arrivals_count = 0;
this.daily_leavers_count = 0;
}
};
construct.prototype.set_options = function(options) {
var property;
for (property in options) {
if (options.hasOwnProperty(property)) {
this.options[property] = options[property];
}
}
this.restart();
};
return construct;
}());