angular.module('homepage').
factory('SidebarHelperSrvc', function (DateUtility, TemplateTimelineService) {
// Store the original data templates copy here (READ ONLY)
var DataStore = {
habit: {
templates: []
},
calendar: {
templates: []
}
};
// Store processed data here. Do not reinitialise object references elsewhere
var sidebar = {
habit: new TaskItems(),
calendar: new TaskItems(),
all: new TaskItems()
};
// Object structure used to store habit and calendar tasks
function TaskItems() {
return {
pending: {},
current: {
morning: [],
afternoon: [],
evening: [],
night: []
},
future: {}
};
}
// NOTE: Any change within sidebar object will update the sidebar
// Complete sidebar object is passed to sidebar module
function resetSidebar(type) {
switch(type) {
case 'CLDR':
sidebar.calendar = new TaskItems();
break;
case 'HABT':
sidebar.habit = new TaskItems();
break;
default:
sidebar.habit = new TaskItems();
sidebar.calendar = new TaskItems();
break;
}
sidebar.all = new TaskItems();
}
function updateDataStore(data) {
if(data.type == 'HABT') {
DataStore.habit.templates.push(data);
}
if(data.type == 'CLDR') {
DataStore.calendar.templates.push(data);
}
}
function updateSidebarData(data) {
if(data.type == 'HABT') {
updateHabitData(data);
}
if(data.type == 'CLDR') {
updateCalendarData(data);
}
mergeAllData();
}
/**
* Adding entries that are to be shown for today
* @param {[type]} data [description]
* @return {[type]} [description]
*/
function updateHabitData(data) {
addItem(data);
}
function updateCalendarData(data) {
// CHECK DATE RANGE
// Add item, if today falls in date range
var today = new Date();
var from = data.data.dates.START.date;
var to = data.data.dates.END.date;
if(DateUtility.isBetweenDates(today, from, to, true, true)) {
addItem(data);
}
}
/**
* Merge habit and calendar item objects
* @return {[type]} [description]
*/
function mergeAllData() {
var morning = sidebar.habit.current.morning.concat(sidebar.calendar.current.morning);
var afternoon = sidebar.habit.current.afternoon.concat(sidebar.calendar.current.afternoon);
var evening = sidebar.habit.current.evening.concat(sidebar.calendar.current.evening);
var night = sidebar.habit.current.night.concat(sidebar.calendar.current.night);
// Assign new array instance
sidebar.all.current.morning = morning.slice();
sidebar.all.current.afternoon = afternoon.slice();
sidebar.all.current.evening = evening.slice();
sidebar.all.current.night = night.slice();
}
/**
* Form task item to be passed to template
* @param {[type]} data [description]
* @return {[type]} [description]
*/
function getItem(data) {
var item = {};
item.hashid = data.data.hashid;
item.isChecked = data.data.isChecked;
if(data.type == 'HABT') {
// Habit with trail and time
if(data.data.time.code == 'TIME') {
item.type = 'HBTT';
item.label = data.data.title;
item.date = data.data.time.date;
}
// Habit with trail only
else {
item.type = 'HBTR';
item.label = data.data.title;
}
}
if(data.type == 'CLDR') {
item.label = data.data.title ? data.data.title : 'Event';
// Calendar meeting with time and location
if(data.data.placetext && data.data.times.START.isDateSet) {
item.type = 'CMTL';
item.times = data.data.times;
item.locationText = data.data.placetext;
}
// Calendar reminder based on time
else if(data.data.times.START.isDateSet) {
item.type = 'CRBT';
item.times = data.data.times;
}
// Calendar reminder without time
else if(!data.data.times.START.isDateSet) {
item.type = 'CMWT';
}
}
return item;
}
/**
* Add item to sidebar data as per time information
*/
function addItemEntry(data, code) {
var today = new Date();
var time;
if(code == 'HABT') {
type = 'habit';
time = data.data.time.date;
code = data.data.time.code || 'TIME';
}
else if(code == 'CLDR') {
type = 'calendar';
time = data.data.times.START.date;
code = 'TIME';
}
time = new Date(time);
// CHECK TIME
// Add as per time else add to current time
if(code == 'MRNG' || (code == 'TIME' && (time.getHours() >= 6 && time.getHours() < 12))) {
sidebar[type].current.morning.push(getItem(data));
}
else if(code == 'AFTN' || (code == 'TIME' && (time.getHours() >= 12 && time.getHours() < 17))) {
sidebar[type].current.afternoon.push(getItem(data));
}
else if(code == 'EVNG' || (code == 'TIME' && (time.getHours() >= 17 && time.getHours() < 20))) {
sidebar[type].current.evening.push(getItem(data));
}
else if(code == 'NGHT' || (code == 'TIME' && (time.getHours() >= 20 && time.getHours() < 24))) {
sidebar[type].current.night.push(getItem(data));
}
else if(code == 'NONE' || code == 'FLDY' ||
(code == 'TIME' && (today.getHours() >= 0 && today.getHours() < 6))) {
if(today.getHours() >= 6 && today.getHours() < 12) {
sidebar[type].current.morning.push(getItem(data));
}
else if(today.getHours() >= 12 && today.getHours() < 17) {
sidebar[type].current.afternoon.push(getItem(data));
}
else if(today.getHours() >= 17 && today.getHours() < 20) {
sidebar[type].current.evening.push(getItem(data));
}
else {
sidebar[type].current.night.push(getItem(data));
}
}
}
function addItem(data) {
var days = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
// CHECK REPETITION
// If Once, check if timestamp matches today
// If Daily, add entry for today
// If Weekly, check if today falls in the choice made
// If Monthly, repeat on same day as timestamp each month
// If Annually, repeat on same date as timestamp each year
var repeats = data.data.repetition.repeats;
var today = new Date();
if(repeats == 'ONCE') {
if(DateUtility.compareDateOnly(data.timestamp, today) === 0) {
addItemEntry(data, data.type);
}
}
else if(repeats == 'DALY') {
addItemEntry(data, data.type);
}
else if(repeats == 'WEEK') {
var type = data.data.repetition.chooseday.type;
var dayofweek = days[today.getDay()];
var chosen = data.data.repetition.chooseday.days;
for(var index in chosen) {
var choice = chosen[index];
if(dayofweek == choice) {
addItemEntry(data, data.type);
}
}
}
else if(repeats == 'MTLY') {
if(today.getDate() == new Date(data.timestamp)) {
addItemEntry(data, data.type);
}
}
else if(repeats == 'ANLY') {
if(today.getDate() == new Date(data.timestamp).getDate()
& today.getMonth() == new Date(data.timestamp).getMonth()) {
addItemEntry(data, data.type);
}
}
}
return {
/**
* Initialize all the data using the list of templates received
*/
initialize: function (templates, type) {
// Reinitialize all data before processing all items
// Resetting without size check would empty all items,
// if habits or calendar items are null and no merge is called
if(templates.length > 0) {
resetSidebar(type);
}
// Process templates only applicable for today
templates = TemplateTimelineService.getItemsByDate(templates);
for(var index in templates) {
var template = templates[index];
updateSidebarData(template);
}
return sidebar;
},
getSidebarByDate: function (templates) {
this.initialize(DataStore.habit.templates, 'HABT');
this.initialize(DataStore.calendar.templates, 'CLDR');
return sidebar;
},
/**
* Return the sidebar object
*/
getSidebarData: function () {
return sidebar;
},
update: function (data) {
updateDataStore(data);
updateSidebarData(data);
return sidebar;
},
/**
* Reset data store
*/
resetAll: function () {
DataStore.habit.templates.length = 0;
DataStore.calendar.templates.length = 0;
resetSidebar();
}
}
});