namespace net.sudormrf.chorechart;

/*
every time you recompile you must:

Remove the umple gen'd getter for User.getTaskIds()
Remove the umple gen'd getter for Items.isBought()

Fix replace umple gen'd getter for ShoppingList.getItems with the one
described bellow (don't know why it compiles the one for Shopping list
but it's ok for User)
*/

strictness expect 1006;

class User {
	String name = "Anon";
	int points = 0;
	String icon = "";
	String id = Facade.getInstance().getUserRef().push().getKey();
	String[] taskIds;

	public List<String> getTaskIds() {
    	return taskIds;
    }

    @Exclude
    public List<Task> getTasks() {
    	List<Task> list = new ArrayList<Task>();
    	for(String taskid : taskIds)
    	{
    		list.add(Facade.getInstance().getTask(taskid));
    	}
    	return list;
    }
}

class Parent {
	isA User;
	void createNewAccount(String name) {

	}
}

class Task {

	public enum Repeat {NEVER, DAILY, WEEKLY, MONTHY, YEARLY}

	String name = "";
	String deadline = "";
	String duration = "Unknown";
	String comment = "";
	boolean completed = false;
	Repeat frequency = Repeat.NEVER;

	String id = Facade.getInstance().getTaskRef().push().getKey();
	String userId = "";

	public User getUser() {
		return Facade.getInstance().getUser(userId);
	}

	public boolean hasAllocation() {
		return userId != "";
	}

	status {
		Unallocated {
			setUserId -> InProgress; //this should check if setUser returns true
			deadlinePassed -> Failed;
		}
		InProgress {
			markCompleted -> Completed;
			release -> Unallocated;
			deadlinePassed -> Failed;
		}
		Completed { renewTask -> InProgress; }
		Failed { extendDeadline -> Unallocated; }
	}

	0..1 -> * Item;
}


class Tools {
	String name;

	* -- * Task;
}

class ShoppingList {
	String name = ""; // list name
	String location = ""; // example hardware or grocery store
	String icon = "";
	String id = Facade.getInstance().getShoppingRef().push().getKey();

	//void createList(String name, Home home, String[] items) {}

	//1 -- 0..1 Task;
	0..1 -> * Item;
}

class Item {
	String name = "";
	String quantity = "";
	Boolean bought = false;
	String id = Facade.getInstance().getShoppingRef().push().getKey();

	public boolean equals(Item other) {
		return this.name.equals(other.name) && this.bought == other.bought;
	}

	//0..* -- 1 ShoppingList;
}

class Home {
	String name;
	String[] userIds;

	//1 -- 1..* Parent;
}

class Facade {
	singleton;

	FirebaseDatabase database = FirebaseDatabase.getInstance();
	DatabaseReference userRef = database.getReference("users");
	DatabaseReference shoppingRef = database.getReference("shopping");
	DatabaseReference taskRef = database.getReference("tasks");

	// Listeners
	void createListeners(final MainActivity.SectionsPagerAdapter sectionsPagerAdapter) {
		userRef.addValueEventListener(new ValueEventListener() {
			@Override
			public void onDataChange(DataSnapshot dataSnapshot) {
				users.clear();

				for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
						User user = userSnapshot.getValue(User.class);
						Facade.getInstance().addUser(user);
				}
				sectionsPagerAdapter.notifyDataSetChanged();
			}

			@Override
			public void onCancelled(DatabaseError error) {
					//don't worry this will definitely never fail (nope)
			}
		});

		shoppingRef.addValueEventListener(new ValueEventListener() {
			@Override
			public void onDataChange(DataSnapshot dataSnapshot) {
				shoppingLists.clear();

				for (DataSnapshot shoppingListSnapshot : dataSnapshot.getChildren()) {
					ShoppingList list = shoppingListSnapshot.getValue(ShoppingList.class);
					Facade.getInstance().addShoppingList(list);
				}
				sectionsPagerAdapter.notifyDataSetChanged();
			}

			@Override
			public void onCancelled(DatabaseError error) {
					//don't worry this will probably never ever fail (never ever)
			}
		});

		taskRef.addValueEventListener(new ValueEventListener() {
			@Override
			public void onDataChange(DataSnapshot dataSnapshot) {
				tasks.clear();

				for (DataSnapshot taskSnapshot : dataSnapshot.getChildren()) {
					Task task = taskSnapshot.getValue(Task.class);
					Facade.getInstance().addTask(task);
				}
				sectionsPagerAdapter.notifyDataSetChanged();
			}

			@Override
			public void onCancelled(DatabaseError error) {
					//don't worry this will never fail (not even once)
			}
		});
	}

	void publishUsers() {
		for (User user : users) {
			this.getUserRef().child(user.getId()).setValue(user);
			this.getUserRef().child(user.getId()).child("taskIds").setValue(user.getTaskIds());
		}
	}

	void publishTasks() {
		for (Task task : tasks) {
			this.getTaskRef().child(task.getId()).setValue(task);
		}
	}

	void publishShoppingLists() {
		for (ShoppingList list : shoppingLists) {
			this.getShoppingRef().child(list.getId()).setValue(list);
		}
	}

	User getUser(String id){
    for (User user : users) {
      if (user.getId().equals(id)) {
        return user;
      }
    }
    return null;
  }

	Task getTask(String id){
    for (Task task : tasks) {
      if (task.getId().equals(id)) {
        return task;
      }
    }
    return null;
  }

	//END OF DATABASE ZONE//

	Home currentHome = new Home("Test Home");
	User currentUser = null;

	void allocateTask(User user, Task task) {
		task.setUserId(user.getId());
		user.addTaskId(task.getId());
	}

	boolean markCompleted(Task task) {
		if(currentUser.getId() == task.getUserId())
			return task.markCompleted();  // Not sure how to respond if task is not InProgress
		return false;
	}

	void addToShopping(ShoppingList list, Item item) {
		list.addItem(item);
	}

	0..1 -> * User;
	0..1 -> * Task;
	0..1 -> * Tools;
	0..1 -> * ShoppingList;
}
