/* Copyright 2009 Palm, Inc.  All rights reserved. */

var ContactsMockService = Class.create({
    initialize: function(){
        // always deep-clone input and output to avoid mixing mock data with JS data
        
        // fix up contactsRawList to add IDs for each contact
        this.gList = contactsRawList.collect(ContactsMockService.extendContact);
        this.gList = this.gList.sortBy(ContactsMockService.getContactSortKey);
        
        this.callbacks = [];
    },
    
    _list: function(offset, limit, filter){
        var results = this.gList.inject([], ContactsMockService.filterContact.curry(offset, limit, filter));
        var wrapped = {};
        wrapped.list = results;
        wrapped.count = results.length;
        return wrapped;
    },
    
    list: function(whoCares, filter, callbackfn, offset, limit){
        if (callbackfn) {
            var toPush = ContactsMockService.apply.curry(callbackfn, this._list.bind(this, offset, limit, filter));
            toPush();
            this.callbacks.push(toPush);
        }
        return new FakeMojoRequest();
    },
    
    _details: function(id){
        var result = ContactsMockService.getContactCopy(this.gList, id);
        var wrapped = {};
        wrapped.record = result;
        if (!result) {
            wrapped.event = "deleted";
        }
        return wrapped;
    },
    
    details: function(id, callbackfn){
        if (callbackfn) {
            var toPush = ContactsMockService.apply.curry(callbackfn, this._details.bind(this, id));
            toPush();
            this.callbacks.push(toPush);
        }
        return new FakeMojoRequest();
    },
    
    _detailPhoneNumbers: function(id){
        var contact = ContactsMockService.getContactCopy(this.gList, id);
        var result = {};
        result.list = [];
        if (contact && contact.phoneNumbers) {
            result.list = contact.phoneNumbers.clone();
        }
        result.count = result.list.size();
        return result;
    },
    
    detailPhoneNumbers: function(id, callbackfn){
        if (callbackfn) {
            var toPush = ContactsMockService.apply.curry(callbackfn, this._detailPhoneNumbers.bind(this, id));
            toPush();
            this.callbacks.push(toPush);
        }
        return new FakeMojoRequest();
    },
    
    _detailIMNames: function(id){
        var contact = ContactsMockService.getContactCopy(this.gList, id);
        var result = {};
        result.list = [];
        if (contact && contact.imNames) {
            result.list = contact.imNames.clone();
        }
        result.count = result.list.size();
        return result;
    },
    
    detailIMNames: function(id, callbackfn){
        if (callbackfn) {
            var toPush = ContactsMockService.apply.curry(callbackfn, this._detailIMNames.bind(this, id));
            toPush();
            this.callbacks.push(toPush);
        }
        return new FakeMojoRequest();
    },
    
    _detailEmails: function(id){
        var contact = ContactsMockService.getContactCopy(this.gList, id);
        var result = {};
        result.list = [];
        if (contact && contact.emailAddresses) {
            result.list = contact.emailAddresses.clone();
        }
        result.count = result.list.size();
        return result;
    },
    
    detailEmails: function(id, callbackfn){
        if (callbackfn) {
            var toPush = ContactsMockService.apply.curry(callbackfn, this._detailEmails.bind(this, id));
            toPush();
            this.callbacks.push(toPush);
        }
        return new FakeMojoRequest();
    },
    
    _detailAddresses: function(id){
        var contact = ContactsMockService.getContactCopy(this.gList, id);
        var result = {};
        result.list = [];
        if (contact && contact.addresses) {
            result.list = contact.addresses.clone();
        }
        result.count = result.list.size();
        return result;
    },
    
    detailAddresses: function(id, callbackfn){
        if (callbackfn) {
            var toPush = ContactsMockService.apply.curry(callbackfn, this._detailAddresses.bind(this, id));
            toPush();
            this.callbacks.push(toPush);
        }
        return new FakeMojoRequest();
    },
    
    save: function(contact, callbackfn){
        if (!contact.id) {
            this.gList.push(contact.deepClone());
        }
        else {
            var indexof = -1;
            this.gList.each(function(c, index){
                if (c.id == contact.id) {
                    indexof = index;
                    throw $break;
                }
            });
            if (indexof != -1) {
                var c = contact.deepClone();
                Mojo.Log.info("found existing to save at index=" + indexof);
                //Mojo.Log.info("overwriting with new contact: " + Object.toJSON(c));
                this.gList[indexof] = c;
            }
        }
        this.callbacks.each(function(cb){
            cb();
        });
    },
    
    // TODO
    doDelete: function(id){
        Mojo.Log.info("deleting this id: " + id);
        var indexof = -1;
        this.gList.each(function(c, index){
            if (c.id == id) {
                indexof = index;
                //Mojo.Log.info("deleting contact: " + c.getFullName());
                throw $break;
            }
        });
        if (indexof != -1) {
            this.gList.splice(indexof, 1);
            this.callbacks.each(function(cb){
                cb()
            });
        }
    }
    
});

ContactsMockService.transformPhone = function(phone){
    var result = {};
    result.value = phone.value;
    result.customLabel = phone.label;
    result.label = 2;
    result.serviceName = phone.serviceName;
    return result;
};

ContactsMockService.transformAddress = function(address){
    var result = {};
    result.streetAddress = address.street;
    result.customLabel = address.label;
    result.label = 2;
    result.zipCode = address.zip;
    result.city = address.city;
    result.state = address.state;
    result.country = address.country;
    
    return result;
};

ContactsMockService.getContactCopy = function(list, id){
    var c = list.find(function(c){
        return c.id == id;
    });
    if (!c) {
        return null;
    }
    var copy = Object.clone(c);
    return copy;
};

ContactsMockService.extendContact = function(contact, index){
    var contactWithId = new Contact();
    contactWithId.id = contact.id;
    if (contact.telephones) {
        contactWithId.phoneNumbers = contact.telephones.collect(ContactsMockService.transformPhone);
    }
    if (contact.emails) {
        contactWithId.emailAddresses = contact.emails.collect(ContactsMockService.transformPhone);
    }
    if (contact.im) {
        contactWithId.imNames = contact.im.collect(ContactsMockService.transformPhone);
    }
    if (contact.addresses) {
        contactWithId.addresses = contact.addresses.collect(ContactsMockService.transformAddress);
    }
    contactWithId.jobTitle = contact.title;
    contactWithId.companyName = contact.nickname;
    contactWithId.firstName = contact.firstName;
    contactWithId.lastName = contact.lastName;
    contactWithId.pictureLoc = contact.imagePath;
    return contactWithId;
};

ContactsMockService.getContactSortKey = function(a){
    var name = "";
    if (a.lastName) {
        name += a.lastName;
    }
    if (a.firstName) {
        name += a.firstName;
    }
    if (a.companyName) {
        name += a.companyName;
    }
    if (!name || name.blank()) {
        return " ";
    }
    return name.toLocaleUpperCase();
};

// returns a contact list entry iff a contact matches the filter
ContactsMockService.filterContact = function(offset, limit, filter, results, contact){
    var capFilter = (filter || "").capitalize();
    var first = contact.firstName || "";
    var last = contact.lastName || "";
    if (capFilter.blank() || first.capitalize().startsWith(capFilter) || last.capitalize().startsWith(capFilter)) {
        var entry = {};
        entry.firstName = contact.firstName;
        entry.lastName = contact.lastName;
        entry.companyName = contact.companyName;
        entry.id = contact.id;
        entry.pictureLoc = contact.pictureLoc;
        results.push(entry);
    }
    // @@ restrict to offset/limit
    return results;
};

// applies fn and applies that result to callback
ContactsMockService.apply = function(callback, fn){
    var delay = Math.random() * 1;
    callback.delay(delay, fn());
};

var FakeMojoRequest = Class.create({
    cancel: function(){
    }
});
