//  @import com.hedgehoglab.application.service.BaseService;
//  @import com.hedgehoglab.solomon.service.exceptions.NoContactsFoundException;

function ContactsService(scope){
    BaseService.call(this,scope);
    var _this=this;

    /**
     * Find all contacts via a search term and/or tag terms
     * @param search_term
     * @param callback
     */
    this.get_contacts_by_search_term=function(search_term,callback){
        var query={};

        if(search_term.term!=null){query.q=search_term.term}
        if(search_term.tags!=null){query.tags=search_term.tags}
// alert("SEARCHING")
        _this.request({
            uri:"/api/contacts?q="+query.q
            ,data:null
            ,type:"GET"
            ,callback:function(e){
				//	Sort although the backend should do this
				// alert(e.contact);
				// if(e && e.contact){
				// 	e.contact=e.contact.sort(function(a,b){
				// 		//	Sort by last name then first name
				// 		var a_name=((a.lastName!=null)?a.lastName:"");//+((a.firstName!=null)?a.firstName:"")
				// 		var b_name=((b.lastName!=null)?b.lastName:"");//+((b.firstName!=null)?b.firstName:"")
				// 		// alert(a_name+" : "+b_name);
				// 		return a_name.toLowerCase()>b_name.toLowerCase();	
				// 	});
				// }
                callback(e);
            }
        });
    }

    /**
     * Get all contacts
     * @param callback
     */
    this.get_contacts=function(callback){
		_this.request({
            uri:"/api/contacts"
            ,data:null
            ,type:"GET"
            ,callback:function(e){                
                callback(e);
            }
        });
    };

	this.get_contacts_lookup=function(callback){
		var _contacts_lookup={};
		
		_this.get_contacts(function(contacts){
			if(contacts && contacts.contact){
				$.each(contacts.contact,function(i,n){
					_contacts_lookup[""+n.id]=n;
				})
			}
		callback(_contacts_lookup,contacts);
		
		});
    };

    /**
     * Find a contact by ID
     * @param id
     * @param callback
     */
    this.get_contact_by_id=function(id,callback){
		_this.request({
            uri:"/api/contacts/"+id
            ,data:null
            ,type:"GET"
            ,callback:function(e){                
                if(callback){
					var c=_this.empty_contact(function(f){
					callback($.extend(f,e));
					});
				}
            }
        });
    };
    

    /**
     * Return various statistics about the contacts in the system
     * @param search_term
     * @param callback
     */
    this.get_contact_counts=function(search_term,callback){
        $.getJSON("/api/backend/search-results-tag-panel",{"q":search_term},function(data){
            callback(data);
        });

    };

    // TODO write a synchronous version of this!
    this.get_tags_for_contacts=function(id,callback){
        $.getJSON("/api/contacts/"+id+"/tags",{},function(data){

            if(data!=null && data.tag){
                if(!$.isArray(data.tag)) data.tag=[data.tag];
                if(data.tag[0]==null) data.tag=[];
            }
            //  NEEDS TO BE FIXED BACKEND issue@?
            callback(data);
        });
    };
    
    /*
    * Returns deals for a contact
    * @param contact id
    * @param callback
    */
    
    this.get_deals_for_contact=function(id,callback){
        _this.request({
            uri:"/api/contacts/"+id+"/deals"
            ,type:"GET"
            ,callback:function(e){
                callback(e);
            }
        });
    }
    
    /**
     * Rob's synchonus function for this.
     */ 
    this.get_tags_for_contact=function(id,callback)
    {
      var result;
      $.ajax({
          type: 'GET',
          url: "/api/contacts/"+id+"/tags",
          dataType: 'json',
          success: function(data) {result=data;
				if (!result) result = {tag:[]};
			      callback(result);
			},
          data: {}
          // async: false
      });
      if (!result) result = {tag:[]};
      return result;
    };

    this.delete_contact=function(contacts,callback){
		//	Loop through and get id's
		var contact_ids=[];
		var c=contacts;
		if(!$.isArray(contacts)) c=[contacts];
		
		$.each(c,function(i,n){
			contact_ids.push(n.id);
		});
		//	DELETE /api/backend/contacts/massdelete/10,6,2
        _this.request({
            uri:"/api/backend/contacts/massdelete/"+(contact_ids.toString())
            ,data:null
            ,type:"DELETE"
            ,callback:function(e){
                //  Remove the item from the list
                callback(e);
            }
        });
    };
    
    this.merge_contacts=function(contact,callback){
      var mergeString = contact.join("-");
      _this.request({
          uri:"/api/backend/merge/"+mergeString
          ,data:null
          ,type:"POST"
          ,callback:function(e){

              callback(e);
          }
      });
    };

    this.new_contact=function(callback){
        _this.request({
            uri:"/api/contacts/"
            ,data:null
            ,type:"POST"
            ,callback:function(e){
                var _c=_this.empty_contact(function(f){
                   callback($.extend(f,_c));
                });
            }
        });
    };

    /**
     * Returns an empty contact
     * @param callback
     */
    this.empty_contact=function(callback){
        var contact={
            "id":null,
            "firstName":"",
            "lastName":"",
            "title":"",
            "info":"",
            "phoneNumbers":{"phoneNumber":[]},
            "emailAddresses":{"emailAddress":[]},
            "addresses":{"address":[]},
            "websites":{"website":[]},
            "companies":{"company":[]},
            "instantMessengers":{"instantMessenger":[]}
            ,"tag":[]
        };
        callback(contact);
    };


    /**
     * Add a new address to the contact 
     * @param contact
     * @param callback
     */
    this.new_address_for_contact=function(contact,callback){
        if(contact.addresses==null){
            contact.addresses={};
            contact.addresses.address=[];
        }

        var address={
                //"id":"1",
                "street":"",
                "city":"",
                "state":"",
                "zip":"",
                "country":"",
                type:address_types.addressType[0]
            }

        contact.addresses.address.push(address);
        callback(address);
    };

    /**
     * Add a new website to the contact
     * @param contact
     * @param callback
     */
    this.new_website_for_contact=function(contact,callback){
        if(contact.websites==null){
            contact.websites={website:[]};
        }

        var website={
                url:"",
                type:website_types.websiteType[0]
            };

        contact.websites.website.push(website);

        callback(website);
    };

    /**
     * Add a new I.M. to the contact
     * @param contact
     * @param callback
     */
    this.new_im_for_contact=function(contact,callback){
        if(contact.instantMessengers==null){
            contact.instantMessengers={instantMessenger:[]};
        }

        var instantMessenger={
                account:"",
                product:messenger_types.enums[0],
				contact:[contact.id]
            };

        contact.instantMessengers.instantMessenger.push(instantMessenger);

        callback(instantMessenger);
    };

	/**
     *
     * @param contact
     * @param callback
	 * /api/contacts/{contact_id}/websites/{website_id}
     */
    this.remove_im_from_contact=function(contact,im,callback){
		if(im.id!=null){
			_this.request({
				uri:"/api/contacts/"+contact.id+"/instantMessengers/"+im.id	// "?q="+query.q
				,data:im
				,type:"DELETE"
				,callback:function(e){}
			});	
		}else{
						
		}
		// 
		callback(im);	
    };
    /**
     *
     * @param contact
     * @param callback
     */
    this.new_phonenumber_for_contact=function(contact,callback){
        if(contact.phoneNumbers==null){
            contact.phoneNumbers={phoneNumber:[]};
        }
        var phonenumber={
            id:null,
            number:"",
            type:phone_types.telephoneType[0]
        };

        contact.phoneNumbers.phoneNumber.push(phonenumber);

        callback(phonenumber);
    };

    /**
     *
     * @param contact
     * @param callback
     */
    this.new_email_address_for_contact=function(contact,callback){
	
		//	Make a post to the email address erver
		
		// http://localhost:8080/contacts#
		if(contact.emailAddresses==null){
            contact.emailAddresses={emailAddress:[]};
        }

		var email_address={
            id:null,
            email:"",
            type:email_types.emailType[0]
        };

		contact.emailAddresses.emailAddress.push(email_address);
        callback(email_address);
    };

	/**
     *
     * @param contact
     * @param callback
	 * /api/contacts/{contact_id}/emails/{email_id} 	
     */
    this.remove_email_address_from_contact=function(contact,email_address,callback){
		//	If its got an ID, make an ajax call else just remove it
		
		if(email_address.id!=null){
			_this.request({
	            uri:"/api/contacts/"+contact.id+"/emails/"+email_address.id	// "?q="+query.q
	            ,data:email_address
	            ,type:"DELETE"
	            ,callback:function(e){                
	            }
	        });	
		}else{
						
		}
		
        callback(email_address);	
    };

	/**
     *
     * @param contact
     * @param callback
	 * /api/contacts/{contact_id}/phonenumbers/{phonenumber_id}
     */
    this.remove_phonenumber_from_contact=function(contact,phonenumber,callback){
		if(phonenumber.id!=null){
			_this.request({
	            uri:"/api/contacts/"+contact.id+"/phonenumbers/"+phonenumber.id	// "?q="+query.q
	            ,data:phonenumber
	            ,type:"DELETE"
	            ,callback:function(e){}
	        });	
		}else{
						
		}
		
        callback(phonenumber);	
    };

	/**
     *
     * @param contact
     * @param callback
	 * /api/contacts/{contact_id}/addresses/{address_id} 
     */
    this.remove_address_from_contact=function(contact,address,callback){
		if(address.id!=null){
			_this.request({
	            uri:"/api/contacts/"+contact.id+"/addresses/"+address.id	// "?q="+query.q
	            ,data:address
	            ,type:"DELETE"
	            ,callback:function(e){}
	        });	
		}else{
						
		}
		
        callback(address);	
    };

	/**
     *
     * @param contact
     * @param callback
	 * /api/contacts/{contact_id}/websites/{website_id}
     */
    this.remove_website_from_contact=function(contact,website,callback){
		if(website.id!=null){
			_this.request({
	            uri:"/api/contacts/"+contact.id+"/websites/"+website.id	// "?q="+query.q
	            ,data:website
	            ,type:"DELETE"
	            ,callback:function(e){}
	        });	
		}else{
						
		}
		
        callback(website);	
    };

	/**
     *
     * @param contact
     * @param callback
	 * /api/contacts/{contact_id}/companies/{company_id}
     */
    this.remove_company_from_contact=function(contact,company,callback){
		if(company.id!=null){
			_this.request({
	            uri:"/api/contacts/"+contact.id+"/companies/"+company.id	// "?q="+query.q
	            ,data:company
	            ,type:"DELETE"
	            ,callback:function(e){}
	        });	
		}else{
						
		}
		
        callback(company);	
    };

    /**
     *
     * @param contact
     * @param callback
     */
    this.new_company_for_contact=function(contact,callback){
        if(contact.companies==null){
            contact.companies={company:[]};
        }

        var company={
            addresses:null,
            emailAddresses:null,
            id:null,
            name:"",
            phoneNumbers:null,
            websites:null
        };
        
        contact.companies.company.push(company);

        callback(company);
    };

    /**
     * 
     * @param contact
     * @param tag
     * @param callback
     */
    this.add_tag_to_contact=function(contact,tag,callback){
        _this.request({
            uri:"/api/contacts/"+contact.id+"/tags"
            ,data:tag
            ,type:"POST"
            ,callback:function(data){
                //  Check.. .. if its already a tag then dont re-add it

                if(contact.tag==null){
                    contact.tag={tag:[]};
                }

                var _exists=false;

                $.each(contact.tag.tag,function(i,n){
                    if(n.id==data.id) _exists=true;
                });

                if(!_exists==true){
                    contact.tag.tag.push(data);    
                }
            
                if(callback){
                    callback({contact:contact,tags:data});
                }
            }
        });
    };

    /**
     *
     * @param contact
     * @param tag
     * @param callback
     */
    this.remove_tag_from_contact=function(contact,tag,callback){
        this.request({
            uri:"/api/contacts/"+contact.id+"/tags/"+tag.id
            ,data:tag
            ,type:"DELETE"
            ,callback:function(data){
                //  Remove the tag from the list
                var ts=[];

                $.each(contact.tag.tag,function(i,n){
                   if(n.id!=tag.id){
                       ts.push(n);
                   }
                });
                
                contact.tag.tag=ts;
                if(callback){
                    callback({contact:contact});
                }
            }
        });
    };

    /**
     * Save a contact
     * @param contact
     * @param callback
     */
    this.save_contact=function(contact,callback){
        normalize(contact);                             //  Resets arrays to null

		
        var meth="PUT";
        var contact_id=null;

        if(contact.id==null){
            meth="POST";
            contact_id="";
        }else{contact_id=contact.id};

        //  Remove objects we dont want to send
        _c=$.extend({},contact);
        _c.note=null;delete _c.note;
        _c.tag=null;delete _c.tag;
        _c.tasks=null;delete _c.task;


		if(contact.companies!=null){
			if(contact.companies.company!=null){
				$.each(contact.companies.company,function(i,n){
					n.id=null;
				});
			}
		}
        //  Make the request
        _this.request({
            uri:"/api/contacts/"+contact_id+""
            ,data:_c
            ,type:meth
            ,callback:function(data){
				// if(data && data.error){
				// 	
				// }
                if(callback){
					callback(data);
                }
            }
        });
    };

    /**
     * Normalize any data i.e. fix any structure discrepencies between back and frontend
     * set attributes to null if they are an empty array
     * @param data
     */
    function normalize(contact,state){
        if(!state){
            if(contact.emailAddresses && contact.emailAddresses.emailAddress.length==0){
                contact.emailAddresses=null;
            }

            if(contact.phoneNumbers && contact.phoneNumbers.phoneNumber.length==0){
                contact.phoneNumbers=null;
            }

            if(contact.addresses && contact.addresses.address.length==0){
                contact.addresses=null;
            }

            if(contact.websites && contact.websites.website.length==0){
                contact.websites=null;
            }
            
            if(contact.companies && contact.companies.company.length==0){
                contact.companies=null;
            }

			// "instantMessengers":{"instantMessenger":[]}
			if(contact.instantMessengers && contact.instantMessengers.instantMessenger.length==0){
                contact.instantMessengers=null;
            }
        }else{
            _this.empty_contact(function(f){
                contact=$.extend(f,contact);
            })
        }
    };

    var email_types = null;
    var phone_types = null;
    var website_types = null;
    var address_types = null;
    var messenger_types = null;

    /*
        Service methods to load types
        TODO - Refactor out into types service
     */
    //  Get types for email/address/telephone etc...
    this.get_email_types=function(callback){
        _this.request({
            uri:"/api/email-types/"
            ,type:"GET"
            ,callback:function(data){email_types = data;callback(data);}
        });
    };

    //  Get types for email/address/telephone etc...
    this.get_phone_types=function(callback){
        _this.request({
            uri:"/api/telephone-types/"
            ,type:"GET"
            ,callback:function(data){phone_types = data;callback(data);}
        });
    };

    this.get_website_types=function(callback){
        _this.request({
            uri:"/api/website-types/"
            ,type:"GET"
            ,callback:function(data){website_types = data;callback(data);}
        });
    };

    this.get_address_types=function(callback){
        _this.request({
            uri:"/api/address-types/"
            ,type:"GET"
            ,callback:function(data){address_types = data;callback(data);}
        });
    };

    this.get_messenger_types=function(callback){
		var _messenger_enums=[
			"AIM",
		    "MSN",
		    "ICQ",
		    "JABBER",
		    "YAHOO",
		    "SKYPE",
		    "QQ",
		    "SAMETIME",
		    "GADUGADU",
		    "GOOGLETALK",
		    "OTHER"
		];
		
		var _messenger_types={
			AIM:{
				"title":"Aim",
				"protocol":"label.contacts.index.im.protocol.AIM"
			},
		    MSN:{
				"title":"MSN",
				"protocol":"label.contacts.index.im.protocol.MSN"
			},
		    ICQ:{
				"title":"ICQ",
				"protocol":"label.contacts.index.im.protocol.ICQ"
			},
		    JABBER:{
				"title":"Jabber",
				"protocol":"label.contacts.index.im.protocol.JABBER"
			},
		    YAHOO:{
				"title":"Yahoo",
				"protocol":"label.contacts.index.im.protocol.YAHOO"
			},
		    SKYPE:{
				"title":"Skype",
				"protocol":"label.contacts.index.im.protocol.SKYPE"
			},
		    QQ:{
				"title":"QQ",
				"protocol":"label.contacts.index.im.protocol.QQ"
			},
		    SAMETIME:{
				"title":"SameTime",
				"protocol":"label.contacts.index.im.protocol.SAMETIME"
			},
		    GADUGADU:{
				"title":"GADUGADU",
				"protocol":"label.contacts.index.im.protocol.GADUGADU"
			},
		    GOOGLETALK:{
				"title":"Google Talk",
				"protocol":"label.contacts.index.im.protocol.GOOGLETALK"
			},
		    OTHER:{
				"title":"Other",
				"protocol":"label.contacts.index.im.protocol.OTHER"
			}	
		}
		
		
		messenger_types = {enums:_messenger_enums,types:_messenger_types};
		callback(messenger_types);
        // _this.request({
        //     uri:"/api/messenger-types/"
        //     ,type:"GET"
        //     ,callback:function(data){messenger_types = data;callback(data);}
        // });
    };
};