var Google = require('googleapis');
var Moment = require('moment-timezone');
var _ = require('lodash');

exports.listEvents = listEvents;

/**
 * Lists events based of the given parameters
 */
function listEvents(callback, auth, options) {
    var calendarArgs = {
        auth: auth,
        singleEvents: true,
        orderBy: 'startTime'
    };
    calendarArgs['maxResults'] = options.count || 10;
    calendarArgs['timeMin'] = options.startDate || (new Date()).toISOString();
    if (options.endDate) {
        calendarArgs['timeMax'] = Moment.tz(options.endDate, 'Europe/Zurich').add(1, 'd').startOf('day').toISOString();
    }
    calendarArgs['calendarId'] = options.calendar || 'primary';

    var calendar = Google.calendar('v3');
    calendar.events.list(
        calendarArgs,
        function(err, response) {
            if (err) {
                callback('The Google Calendar API returned an error: ' + err);
                return;
            }
            var events = _.map(response.items, function(event) {
                return handleEvent(event, options.hours);
            });
            callback(null, events);
        }
    );
}

function handleEvent(event, hours) {
    var start = event.start.dateTime || event.start.date;
    start = Moment.tz(start, 'Europe/Zurich');
    var end = event.end.dateTime || event.end.date;
    end = Moment.tz(end, 'Europe/Zurich');

    var time;
    if (hours) {
        time = (Math.round(end.diff(start, "hours", true) * 100) / 100).toString();
    } else {
        time = start.format('HH:mm') + '-' + end.format('HH:mm');
    }

    var msg = {
        'project': 'xxx',
        'time': time,
        'text': event.summary,
        'timestamp': start.startOf('day').format('X'),
        'comment': false,
        'type': 'calendar'
    };
    
    // check my response to event (accepted/tentative/declined)
    if (_.has(event, 'attendees')) {
        var selfResponse = _.find(event.attendees, function(attendee) {
            return _.has(attendee, 'self') && attendee.self;
        });
        if (selfResponse && _.includes(['tentative', 'declined'], selfResponse.responseStatus)) {
            msg.comment = true;
            msg.text = msg.text + ' ('+ selfResponse.responseStatus.toUpperCase() + ')';
        }
    }

    return msg;
}

@@ -102,115 +102,72 @@
 );%0A%0A
-exports.listEvents = listEvents;%0A%0A/**%0A * Lists events based of the given parameters%0A */%0Afunction listEvents
+function Calendar() %7B%7D%0A%0ACalendar.prototype.listEvents = function
 (cal
@@ -186,24 +186,43 @@
  options) %7B%0A
+    var me = this;%0A
     var cale
@@ -1021,16 +1021,19 @@
  return 
+me.
 handleEv
@@ -1133,30 +1133,52 @@
 );%0A%7D
+;
 %0A%0A
-function handleEvent
+Calendar.prototype.handleEvent = function
 (eve
@@ -2306,9 +2306,44 @@
 n msg;%0A%7D
+;%0A%0Amodule.exports = new Calendar();
 %0A

Refactor calendar module as prototype object