package util.misc;
import gui.forms.GUIMain;
import util.Timer;
import util.Utils;
import util.settings.Settings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Created by Nick on 8/8/2014.
*/
public class Vote extends Thread {
private int time, totalVotes;
private Timer pollTime;
private boolean isDone;
private String channel;
public boolean isDone() {
return isDone;
}
public int getTotalVotes()
{
return totalVotes;
}
public List<Option> options;
public Vote(String channel, int time, String... options) {
this.channel = channel;
isDone = false;
this.time = time;
this.totalVotes = 0;
this.options = createOptions(options);
}
private List<Option> createOptions(String[] options)
{
List<Option> toReturn = new CopyOnWriteArrayList<>();
for (int i = 0; i < options.length; i++) {
Option o = new Option(options[i], i + 1, this);
toReturn.add(o);
}
return toReturn;
}
public void addVote(String name, int option)
{
if (option > options.size() || option < 1) return;
Option vote = getOption(name);
if (vote != null) {//they already voted
if (vote.compare != option) {//but now it's for a different
vote.decrease(name);
totalVotes--;
} else {
return; // They already voted for this!
}
}
option--;
Option newVote = options.get(option);
newVote.increment(name);
totalVotes++;
// Update the GUI
if (GUIMain.voteGUI != null && GUIMain.voteGUI.isVisible())
GUIMain.voteGUI.updatePoll(this);
}
@Override
public void start()
{
pollTime = new Timer(Utils.handleInt(time));
printStart();
super.start();
}
@Override
public void run() {
while (!GUIMain.shutDown && pollTime.isRunning()) {
try {
sleep(20);
} catch (Exception ignored) {
}
}
if (!isDone) {
isDone = true;
printResults();
}
}
@Override
public void interrupt() {
isDone = true;
super.interrupt();
}
/**
* Gets an Option that the user is in, otherwise null.
*
* @param user The user to check.
* @return The option they voted for, otherwise null.
*/
private Option getOption(String user)
{
for (Option o : options) {
if (o.count > 0) {
for (String voter : o.voters) {
if (voter.equalsIgnoreCase(user)) {
return o;
}
}
}
}
return null;
}
public class Option implements Comparable<Option>
{
private String name;
List<String> voters;
int count = 0;
int compare;
private Vote parent;
Option(String name, int compareIndex, Vote parent)
{
this.name = name;
compare = compareIndex;
voters = new ArrayList<>();
this.parent = parent;
}
void increment(String name) {
count++;
voters.add(name);
}
void decrease(String name) {
count--;
voters.remove(name);
}
public int getCount()
{
return count;
}
public String getName()
{
return name;
}
public Vote getParent()
{
return parent;
}
@Override
public int compareTo(Option o) {
if (o.count > this.count) {
return -1;
} else if (o.count == this.count) {
return 0;
} else {
return 1;
}
}
}
public void printStart() {
Settings.accountManager.getBot().sendMessage(channel, "Vote started! " +
"Everybody has " + time + " seconds to vote! To vote, type \"!vote #\" where # represents your choice!");
for (int i = 0; i < options.size(); i++) {
Settings.accountManager.getBot().sendMessage(channel, (i + 1) + ": " + options.get(i).name);
}
}
public void printResults() {
String[] results = getResults();
for (String s : results) {
Settings.accountManager.getBot().sendMessage(channel, s);
}
if (GUIMain.voteGUI != null && GUIMain.voteGUI.isVisible())
GUIMain.voteGUI.pollEnded(this);
}
public String[] getResults() {
ArrayList<String> resultStrings = new ArrayList<>();
resultStrings.add("The results to the poll are:");
ArrayList<Option> results = getSortedOptions();
int totalVotes = 0;
for (Option o : results) {
totalVotes += o.count;
}
if (totalVotes > 0) {
for (Option o : results) {
resultStrings.add(o.name + ": " + o.count + "/" + totalVotes + " (" + (int) (((double) o.count / (double) totalVotes) * 100) + "%)");
}
} else {
resultStrings.add("Nobody voted for anything. BibleThump");
}
return resultStrings.toArray(new String[resultStrings.size()]);
}
private ArrayList<Option> getSortedOptions() {
ArrayList<Option> results = new ArrayList<>();
results.addAll(options);
Collections.sort(results);//sort into ascending based on votes
Collections.reverse(results);//make it descending
return results;
}
}