001    package com.skype.api;
002    
003    import java.io.IOException;
004    import java.util.*;
005    import com.skype.ipc.*;
006    /**
007     * Address book entry. Encapsulates methods like GetType, GetIdentity, GetAvatar, SendAuthRequest, OpenConversation etc. Single contact can have additional phone numbers attached to it (ASSIGNED_PHONE1 .. ASSIGNED_PHONE3). Note that in the context of a conversation, Contacts are represented by Participant objects. Contact member functions all return a Boolean indicating the success (true) or failure (false) of processing the request itself (transport, runtime availability, and so forth)?not the success or failure of its associated functionality. For example, Contact.IsMemberOf returns true if it was able to make a determination, and its result parameter reflects whether this Contact is a member of the target group. Similarly, Contact.IsMemberOf returns false if it was unable to make a determination, and the value of its result parameter is undefined. <br>
008     */
009    
010    
011    public class Contact extends SkypeObject {
012    
013    
014            public interface ContactListener {
015                    /** This event gets called when there are changes to Contact properties defined in Contact.PROPERTY  */
016                    public void OnPropertyChange(SkypeObject obj, PROPERTY prop, Object value);
017                    
018            }
019            
020            public Contact(int oid, Skype skype) {
021                    super(oid,skype);
022                    /**get default properties for this module **/
023                    GetDefaultProps();
024            }
025            
026            private static final int MODULE_ID = 2;
027            
028            public static final int moduleID() {
029                    return MODULE_ID;
030            }
031            
032            /** Properties of the Contact class */
033            public enum PROPERTY {
034            
035                    /** type: Contact.TYPE */
036                    type(202),
037                    
038                    /** defined if it is a SKYPE contact, type: String */
039                    skypename(4),
040                    
041                    /** type: String */
042                    pstnnumber(6),
043                    
044                    /** type: String */
045                    fullname(5),
046                    
047                    /** integer of YYYYMMDD format, type: int */
048                    birthday(7),
049                    
050                    /** 1-male, 2-female, type: int */
051                    gender(8),
052                    
053                    /** ISO language code list, space separated, type: String */
054                    languages(9),
055                    
056                    /** ISO country code, type: String */
057                    country(10),
058                    
059                    /** type: String */
060                    province(11),
061                    
062                    /** type: String */
063                    city(12),
064                    
065                    /** This corresponds to the Account.P_PHONE_HOME property. The value is set by the remote user in Account profile. As Contact property, this is read-only. <br>, type: String */
066                    phone_home(13),
067                    
068                    /** This corresponds to the Account.P_PHONE_OFFICE property. The value is set by the remote user in Account profile. As Contact property, this is read-only. If the Contact has not populated his Account profile with sufficient phone numbers, the UI should implement locally adding additional phone numbers to Contact P_ASSIGNED_PHONE1 .. P_ASSIGNED_PHONE3 properties (and corresponding labels). See Contact.SetPhoneNumber method for more information. <br>, type: String */
069                    phone_office(14),
070                    
071                    /** This corresponds to the Account.P_PHONE_MOBILE property. The value is set by the remote user in Account profile. As Contact property, this is read-only. <br>, type: String */
072                    phone_mobile(15),
073                    
074                    /** will be hashed before advertising/querying, space separated, type: String */
075                    emails(16),
076                    
077                    /** type: String */
078                    homepage(17),
079                    
080                    /** arbitrary introductory text, type: String */
081                    about(18),
082                    
083                    /** Contact avatar pictures are in JPG format. The original size of avatar pictures are in no more than 96 x 96 pixels in size. However, as they can be smaller, scaling the pictures up too much to fit your UI can lead to distorted images. <br>, type: byte[] */
084                    avatar_image(37),
085                    
086                    /** Personal mood message (visible to authorized users only).  <br>, type: String */
087                    mood_text(26),
088                    
089                    /** XML version of personal mood text, type: String */
090                    rich_mood_text(205),
091                    
092                    /** 24*3600+diff_to_UTC_in_seconds. NB! changes with DST <br>, type: int */
093                    timezone(27),
094                    
095                    /** binary tag that can be queried via Contact.HasCapability(), type: byte[] */
096                    capabilities(36),
097                    
098                    /** UNIX timestamp of last profile change, type: int */
099                    profile_timestamp(19),
100                    
101                    /** count of this user's authorized contacts <br>, type: int */
102                    nrof_authed_buddies(28),
103                    
104                    /** ISO country code assigned by the IP, type: String */
105                    ipcountry(29),
106                    
107                    /** UNIX timestamp of when current avatar was set, type: int */
108                    avatar_timestamp(182),
109                    
110                    /** UNIX timestamp of when current mood was set, type: int */
111                    mood_timestamp(183),
112                    
113                    /** set if the contact is waiting to be authorized. The value contains auth. request text <br>, type: String */
114                    received_authrequest(20),
115                    
116                    /** timestamp of last received auth-request, type: int */
117                    authreq_timestamp(25),
118                    
119                    /** X timestamp of last successful ping to that user, type: int */
120                    lastonline_timestamp(35),
121                    
122                    /** Contact.AVAILABILITY, type: AVAILABILITY */
123                    availability(34),
124                    
125                    /** always set (assigned by lib by looking at various fields), type: String */
126                    displayname(21),
127                    
128                    /** true if querying additional information from p2p or server <br>, type: boolean */
129                    refreshing(22),
130                    
131                    /** Contact.AUTHLEVEL, change via Contact.GiveAuthlevel(), type: AUTHLEVEL */
132                    given_authlevel(23),
133                    
134                    /** change via Contact.GiveDisplayname(), type: String */
135                    given_displayname(33),
136                    
137                    /** change via Contact.AssignComment(), type: String */
138                    assigned_comment(180),
139                    
140                    /** UNIX timestamp of last outbound session (call, chat, FT, etc), type: int */
141                    lastused_timestamp(39),
142                    
143                    /** for contacts that have CONTACT_RECEIVED_AUTHREQUEST, how many times in a row they have requested it without positive answer, type: int */
144                    authrequest_count(41),
145                    
146                    /** Office phone no. of the contact. This property should NOT be used for SkypeOut contacts <br>, type: String */
147                    assigned_phone1(184),
148                    
149                    /** Value "1" in this property will be translated as "Office" by Skype Windows desktop client, according to UI language settings <br>, type: String */
150                    assigned_phone1_label(185),
151                    
152                    /** Mobile phone no. of the contact <br>, type: String */
153                    assigned_phone2(186),
154                    
155                    /** Value "2" in this property will be translated as "Mobile" by Skype Windows desktop client, according to UI language settings <br>, type: String */
156                    assigned_phone2_label(187),
157                    
158                    /** "Other phone no. of the contact, type: String */
159                    assigned_phone3(188),
160                    
161                    /** Value "3" in this property will be translated as "Other" by Skype Windows desktop client, according to UI language settings <br>, type: String */
162                    assigned_phone3_label(189),
163                    
164                    /** Contact's order by presence popularity <br>, type: int */
165                    popularity_ord(42);
166                    
167                    private static final Map<Integer,PROPERTY> lookup = new HashMap<Integer,PROPERTY>();
168                    
169                    static {
170                            for(PROPERTY s : EnumSet.allOf(PROPERTY.class))
171                                    lookup.put(s.getId(), s);
172                    }
173                    
174                    private final int id;
175                    
176                    private PROPERTY(int value) {
177                            this.id = value;
178                    }
179                    
180                    public int getId() { return id; }
181                    
182                    public static PROPERTY get(int code) {
183                            return lookup.get(code);
184                    }
185                    
186                    public static PROPERTY fromString(String s) {
187                            for (PROPERTY p : lookup.values()) {
188                                    if (p.toString() == s) {
189                                            return p;
190                                    }
191                            }
192                            return null;
193                    }
194            }
195            
196            public Object GetPropertyAsEnum(int propid) {
197                    return PROPERTY.get(propid);
198            }
199            
200            public String GetStrProperty(PROPERTY prop) {
201                    //check in propcache if so then return
202                    if (mPropCache.containsKey(new Integer(prop.id))){
203                            String value =  (String)mPropCache.get(prop.id);
204                            if (value != null && !(value.length() == 0) ){
205                                    return value;
206                            }
207                    }
208                    //else get from skypekit...
209                    GetPropertyRequest request = new GetPropertyRequest(2, mObjectId, prop.id);
210                    
211                    String string = null;
212                    GetPropertyResponse r = skype.GetProperty(request);
213                    if (r != null){
214                            string = r.GetAsString();
215                    }
216                    
217                    if (string != null)
218                    {
219                            mPropCache.put(new Integer(prop.id), string);
220                    }
221                    return string;
222            }
223            
224            public int GetIntProperty(PROPERTY prop) {
225                    //check in propcache if so then return
226                    if (mPropCache.containsKey(new Integer(prop.id))){
227                            int value = ((Integer)mPropCache.get(prop.id)).intValue();
228                            if (value != 0){
229                                    return value;
230                            }
231                    }
232                    //else get from skypekit...
233                    GetPropertyRequest request = new GetPropertyRequest(moduleID(), mObjectId, prop.id);
234                    
235                    Integer integer = null;
236                    GetPropertyResponse r = skype.GetProperty(request);
237                    if (r != null){
238                            integer  = r.GetAsInt();
239                    }
240                    
241                    if (integer != null)
242                    {
243                            mPropCache.put(new Integer(prop.id), integer);
244                            return integer.intValue();
245                    }
246                    else
247                    {
248                            return 0;
249                    }
250            }
251            
252            public boolean GetBooleanProperty(PROPERTY prop) {
253                    //check in propcache if so then return
254                    if (mPropCache.containsKey(new Integer(prop.id))){
255                            return ((Boolean)mPropCache.get(prop.id)).booleanValue();
256                    }
257                    //else get from skypekit...
258                    GetPropertyRequest request = new GetPropertyRequest(moduleID(), mObjectId, prop.id);
259                    
260                    Boolean boolResp = null;
261                    GetPropertyResponse r = skype.GetProperty(request);
262                    if (r != null){
263                            boolResp  = r.GetAsBoolean();
264                    }
265                    
266                    if (boolResp != null)
267                    {
268                            mPropCache.put(new Integer(prop.id), boolResp);
269                            return boolResp.booleanValue();
270                    }
271                    else
272                    {
273                            return false;
274                    }
275            }
276            
277            public byte [] GetBinProperty(PROPERTY prop) {
278                    //get from skypekit...
279                    GetPropertyRequest request = new GetPropertyRequest(2, mObjectId, prop.id);
280                    
281                    byte [] data = null;
282                    GetPropertyResponse r = skype.GetProperty(request);
283                    if (r != null) {
284                            data = r.GetAsBinary();
285                    }
286                    return data;
287            }
288            
289            /**default array of Contact Properties that get fetched & cached upon class construction*/
290            private static PROPERTY [] defaultProperties = { PROPERTY.type, PROPERTY.skypename, PROPERTY.fullname, PROPERTY.displayname, PROPERTY.mood_text, PROPERTY.pstnnumber, PROPERTY.availability, PROPERTY.given_displayname};
291            
292            private void GetDefaultProps() {
293                    MultiGetPropertyRequest request = null;
294                    ArrayList<Integer> proparray = null;
295                            /**Add the single oid into array*/
296                            ArrayList<Integer> oidarray=new ArrayList<Integer>();
297                            oidarray.add(mObjectId);
298                            
299                            /**Add all requested propids into array*/
300                            proparray=new ArrayList<Integer>();
301                            for (PROPERTY defaultProp : defaultProperties) {
302                                    proparray.add(defaultProp.getId());
303                            }
304                            /**Generate the request*/
305                            request = new MultiGetPropertyRequest(moduleID(), oidarray,proparray);
306                            
307                            /** Make Multi Get call*/
308                            GetPropertyResponse r=skype.MultiGetProperty(request);
309                            /**Verify that it is a proper multiresponse*/
310                            if(!r.isMultiresponse())
311                            {
312                                    return;
313                            }
314                            /**update property cache with results*/
315                            mPropCache.putAll(r.GetAsMap(mObjectId, proparray));
316                    }
317                    
318                    /**
319                    Same as with CAPABILITY, enumerator is used by both Contact and Account objects. <br> */
320                    public enum TYPE {
321                    
322                            /** Contact/account has no pre-identified type. This type is reported by default for SkypeKit clients. <br>*/
323                            UNRECOGNIZED(0),
324                            
325                            /** Normal Skype contact. <br>*/
326                            SKYPE(1),
327                            
328                            /** Normal PSTN contact. <br>*/
329                            PSTN(2),
330                            
331                            /** Emergency number (i.e. 911). <br>*/
332                            EMERGENCY_PSTN(3),
333                            
334                            /** */
335                            FREE_PSTN(4),
336                            
337                            /** Undisclosed PSTN number. <br>*/
338                            UNDISCLOSED_PSTN(5),
339                            
340                            /** This type is currently used by Windows desktop clients for contacts imported from Outlook. <br>*/
341                            EXTERNAL(6);
342                            
343                            private static final Map<Integer,TYPE> lookup = new HashMap<Integer,TYPE>();
344                            
345                            static {
346                                    for(TYPE s : EnumSet.allOf(TYPE.class))
347                                            lookup.put(s.getId(), s);
348                            }
349                            
350                            private final int id;
351                            
352                            private TYPE(int value) {
353                                    this.id = value;
354                            }
355                            
356                            public int getId() { return id; }
357                            
358                            public static TYPE get(int code) {
359                                    return lookup.get(code);
360                            }
361                            
362                            public static TYPE fromString(String s) {
363                                    for (TYPE p : lookup.values()) {
364                                            if (p.toString() == s) {
365                                                    return p;
366                                            }
367                                    }
368                                    return null;
369                            }
370                    }
371                    
372                    /**
373                     *Getter method for the TYPE property. <br>
374                     * @return type
375                     */
376                    public TYPE GetType() {
377                    
378                            Request request = null;
379                            try {
380                                    request = new XCallRequest(2,1);
381                            } catch (IOException e) {
382                                    e.printStackTrace();
383                                    if (skype.errorListener != null)
384                                            skype.errorListener.OnSkypeKitFatalError();
385                            }
386                            request.addParm('O',0,mObjectId);
387                            
388                            Response r = skype.XCall((XCallRequest)request);
389                            
390                            if (r.isErrCall())
391                                    return null;
392                                    
393                            TYPE type = null;
394                            type = TYPE.get(r.GetAsInt(1));
395                            return type;
396                    }
397                    
398                    /**
399                    Describes the recognized relational states between a local account and a remote contact. <br> */
400                    public enum AUTHLEVEL {
401                    
402                            /** Authorization request is either ignored or pending. In this state several functionalities may be blocked, depending on settings. For example, accounts may only allow seeing online presence to be viewable or only receive calls from authorized contacts. <br>*/
403                            NONE(0),
404                            
405                            /** Contact has been authorized by the local account. <br>*/
406                            AUTHORIZED_BY_ME(1),
407                            
408                            /** Contact has been blocked by the local account. This prevents incoming calls, chat messages, additional authorization requests etc. <br>*/
409                            BLOCKED_BY_ME(2);
410                            
411                            private static final Map<Integer,AUTHLEVEL> lookup = new HashMap<Integer,AUTHLEVEL>();
412                            
413                            static {
414                                    for(AUTHLEVEL s : EnumSet.allOf(AUTHLEVEL.class))
415                                            lookup.put(s.getId(), s);
416                            }
417                            
418                            private final int id;
419                            
420                            private AUTHLEVEL(int value) {
421                                    this.id = value;
422                            }
423                            
424                            public int getId() { return id; }
425                            
426                            public static AUTHLEVEL get(int code) {
427                                    return lookup.get(code);
428                            }
429                            
430                            public static AUTHLEVEL fromString(String s) {
431                                    for (AUTHLEVEL p : lookup.values()) {
432                                            if (p.toString() == s) {
433                                                    return p;
434                                            }
435                                    }
436                                    return null;
437                            }
438                    }
439                    
440                    /**
441                    Describes the superset list of possible Account and Contact online statuses. In case of Account they apply to local user, in case of Contact they apply to remote contacts. <br> */
442                    public enum AVAILABILITY {
443                    
444                            /** Contact online status cannot be determined. This availability state should not normally reach the SkypeKit UI level. <br>*/
445                            UNKNOWN(0),
446                            
447                            /** Seeing Contact online status is blocked because authorization between contact and local account has not taken place. <br>*/
448                            PENDINGAUTH(8),
449                            
450                            /** Remote contact has been blocked by local account. This applies to online accounts. <br>*/
451                            BLOCKED(9),
452                            
453                            /** Remote SkypeOut contact has been blocked by local account. <br>*/
454                            BLOCKED_SKYPEOUT(11),
455                            
456                            /** Contact does not have an online status because he is a PSTN contact. <br>*/
457                            SKYPEOUT(10),
458                            
459                            /** Contact appears to be offline. <br>*/
460                            OFFLINE(1),
461                            
462                            /** Contact appears to be offline but has voicemail enabled. <br>*/
463                            OFFLINE_BUT_VM_ABLE(12),
464                            
465                            /** Contact appears to be offline but has enabled call forwarding, so calls may actually get through to him. <br>*/
466                            OFFLINE_BUT_CF_ABLE(13),
467                            
468                            /** Contact / Account is online <br>*/
469                            ONLINE(2),
470                            
471                            /** Contact / Account is online but away from keyboard. This can be either turned on manually or by automatic timer. In Windows desktop client, the timer can be configured with minute precision. <br>*/
472                            AWAY(3),
473                            
474                            /** This online status is marked as deprecated. If a remote contact indicates its status as NOT_AVAILABLE, the UI should handle this as equivalent of AWAY status. <br>*/
475                            NOT_AVAILABLE(4),
476                            
477                            /** Contact / Account is online but does not wish to be disturbed. This status supersedes AWAY status when the account is DO_NOT_DISTURB the AWAY timer should not modify the status. <br>*/
478                            DO_NOT_DISTURB(5),
479                            
480                            /** This online status is marked as deprecated. If a remote contact indicates its status as SKYPE_ME, the UI should handle this as equivalent of ONLINE status. <br>*/
481                            SKYPE_ME(7),
482                            
483                            /** Account status is set to INVISIBLE. This status in not applicable to remote Contacts. When the remote contact has set his availability to INVISIBLE, he will appear as OFFLINE to others. <br>*/
484                            INVISIBLE(6),
485                            
486                            /** only possible for local user/account*/
487                            CONNECTING(14),
488                            
489                            /** */
490                            ONLINE_FROM_MOBILE(15),
491                            
492                            /** *_FROM_MOBILE only possible for remote user*/
493                            AWAY_FROM_MOBILE(16),
494                            
495                            /** */
496                            NOT_AVAILABLE_FROM_MOBILE(17),
497                            
498                            /** */
499                            DO_NOT_DISTURB_FROM_MOBILE(18),
500                            
501                            /** */
502                            SKYPE_ME_FROM_MOBILE(20);
503                            
504                            private static final Map<Integer,AVAILABILITY> lookup = new HashMap<Integer,AVAILABILITY>();
505                            
506                            static {
507                                    for(AVAILABILITY s : EnumSet.allOf(AVAILABILITY.class))
508                                            lookup.put(s.getId(), s);
509                            }
510                            
511                            private final int id;
512                            
513                            private AVAILABILITY(int value) {
514                                    this.id = value;
515                            }
516                            
517                            public int getId() { return id; }
518                            
519                            public static AVAILABILITY get(int code) {
520                                    return lookup.get(code);
521                            }
522                            
523                            public static AVAILABILITY fromString(String s) {
524                                    for (AVAILABILITY p : lookup.values()) {
525                                            if (p.toString() == s) {
526                                                    return p;
527                                            }
528                                    }
529                                    return null;
530                            }
531                    }
532                    
533                    /**
534                     * @return identity returns CONTACT_SKYPENAME or CONTACT_PSTNNUMBER value
535                     */
536                    public String GetIdentity() {
537                    
538                            Request request = null;
539                            try {
540                                    request = new XCallRequest(2,2);
541                            } catch (IOException e) {
542                                    e.printStackTrace();
543                                    if (skype.errorListener != null)
544                                            skype.errorListener.OnSkypeKitFatalError();
545                            }
546                            request.addParm('O',0,mObjectId);
547                            
548                            Response r = skype.XCall((XCallRequest)request);
549                            
550                            if (r.isErrCall())
551                                    return null;
552                                    
553                            String identity = null;
554                            identity = r.GetAsString(1);
555                            return identity;
556                    }
557                    
558                    /**
559                     *Returns Conrtact's avatar image (JPG). <br>
560                     * @return GetAvatarResult
561                     */
562                    public GetAvatarResult GetAvatar() {
563                    
564                            Request request = null;
565                            try {
566                                    request = new XCallRequest(2,4);
567                            } catch (IOException e) {
568                                    e.printStackTrace();
569                                    if (skype.errorListener != null)
570                                            skype.errorListener.OnSkypeKitFatalError();
571                            }
572                            request.addParm('O',0,mObjectId);
573                            
574                            Response r = skype.XCall((XCallRequest)request);
575                            
576                            if (r.isErrCall())
577                                    return null;
578                                    
579                            GetAvatarResult result = new GetAvatarResult();
580                            
581                            boolean present = false;
582                            present = r.GetAsBoolean(1);
583                            result.present = present;
584                            
585                            byte[] avatar = null;
586                            avatar = r.GetAsBinary(2);
587                            result.avatar = avatar;
588                            
589                            return result;
590                    }
591                    
592                    public class GetAvatarResult {
593                            public boolean present; /** <br> - true: the Contact has a custom avatar image <br> - false: the Contact does not have a custom avatar image <br> */
594                            public byte[] avatar; /** The avatar image data (JPG). If present is false, this will be the Skype-assigned default avatar <br> */
595                    }
596                    
597                    /**
598                     *returns verified-by-Skype e-mail for this contact if exists and verifiable
599                     * @return email
600                     */
601                    public String GetVerifiedEmail() {
602                    
603                            Request request = null;
604                            try {
605                                    request = new XCallRequest(2,3);
606                            } catch (IOException e) {
607                                    e.printStackTrace();
608                                    if (skype.errorListener != null)
609                                            skype.errorListener.OnSkypeKitFatalError();
610                            }
611                            request.addParm('O',0,mObjectId);
612                            
613                            Response r = skype.XCall((XCallRequest)request);
614                            
615                            if (r.isErrCall())
616                                    return null;
617                                    
618                            String email = null;
619                            email = r.GetAsString(1);
620                            return email;
621                    }
622                    
623                    /**
624                     *returns verified-by-Skype company for this contact if exists and verifiable
625                     * @return company
626                     */
627                    public String GetVerifiedCompany() {
628                    
629                            Request request = null;
630                            try {
631                                    request = new XCallRequest(2,8);
632                            } catch (IOException e) {
633                                    e.printStackTrace();
634                                    if (skype.errorListener != null)
635                                            skype.errorListener.OnSkypeKitFatalError();
636                            }
637                            request.addParm('O',0,mObjectId);
638                            
639                            Response r = skype.XCall((XCallRequest)request);
640                            
641                            if (r.isErrCall())
642                                    return null;
643                                    
644                            String company = null;
645                            company = r.GetAsString(1);
646                            return company;
647                    }
648                    
649                    /**
650                     *Checks whether the contact is member of a contact group given in group reference argument. <br>
651                     * @param group The target contact group <br>
652                     * @return result <br> - true: the Contact is a member of the target contact group <br> - false: the Contact is not a member of the target contact group <br>
653                     */
654                    public boolean IsMemberOf( ContactGroup group) {
655                    
656                            Request request = null;
657                            try {
658                                    request = new XCallRequest(2,6);
659                            } catch (IOException e) {
660                                    e.printStackTrace();
661                                    if (skype.errorListener != null)
662                                            skype.errorListener.OnSkypeKitFatalError();
663                            }
664                            request.addParm('O',0,mObjectId);
665                            request.addParm('O',1,group.getOid());
666                            
667                            Response r = skype.XCall((XCallRequest)request);
668                            
669                            if (r.isErrCall())
670                                    return false;
671                                    
672                            boolean result = false;
673                            result = r.GetAsBoolean(1);
674                            return result;
675                    }
676                    
677                    /**
678                     *Checks whether the contact is member of a pre-defined contact group given in the TYPE argument (type for this property comes from the ContactGroup class). <br>
679                     * @param groupType The type designator of the target pre-defined contact group. For example, specify this parameter as ContactGroup.TYPE.RECENTLY_CONTACTED_CONTACTS to determine if you've had a recent conversation with this Contact. <br>
680                     * @return result <br> - true: the Contact is a member of the target contact group <br> - false: the Contact is not a member of the target contact group <br>
681                     */
682                    public boolean IsMemberOfHardwiredGroup( ContactGroup.TYPE groupType) {
683                    
684                            Request request = null;
685                            try {
686                                    request = new XCallRequest(2,7);
687                            } catch (IOException e) {
688                                    e.printStackTrace();
689                                    if (skype.errorListener != null)
690                                            skype.errorListener.OnSkypeKitFatalError();
691                            }
692                            request.addParm('O',0,mObjectId);
693                            request.addParm('e',1,groupType.getId());
694                            
695                            Response r = skype.XCall((XCallRequest)request);
696                            
697                            if (r.isErrCall())
698                                    return false;
699                                    
700                            boolean result = false;
701                            result = r.GetAsBoolean(1);
702                            return result;
703                    }
704                    
705                    /**
706                     *Blocks or unblocks any further incoming communication attempts from this contact. <br>
707                     * @param blocked <br> - true: block this contact <br> - false: unblock this contact <br>
708                     * @param abuse Optional parameter to report abuse by this Skype user when blocking this Contact. Note that you can specifiy this parameter as true only when blocking a Contact. Defaults to false if omitted. <br>
709                     */
710                    public void SetBlocked( boolean blocked, boolean abuse) {
711                    
712                            Request request = null;
713                            try {
714                                    request = new XCallRequest(2,22);
715                            } catch (IOException e) {
716                                    e.printStackTrace();
717                                    if (skype.errorListener != null)
718                                            skype.errorListener.OnSkypeKitFatalError();
719                            }
720                            request.addParm('O',0,mObjectId);
721                            request.addParm('b',1,blocked);
722                            request.addParm('b',2,abuse);
723                            
724                            skype.XCall((XCallRequest)request);
725                    }
726                    
727                    /**
728                     *Rejects and removes a pending authorization request from this Contact. <br>
729                     */
730                    public void IgnoreAuthRequest() {
731                    
732                            Request request = null;
733                            try {
734                                    request = new XCallRequest(2,21);
735                            } catch (IOException e) {
736                                    e.printStackTrace();
737                                    if (skype.errorListener != null)
738                                            skype.errorListener.OnSkypeKitFatalError();
739                            }
740                            request.addParm('O',0,mObjectId);
741                            
742                            skype.XCall((XCallRequest)request);
743                    }
744                    
745                    /**
746                     *sets CONTACT_GIVEN_DISPLAYNAME. clears if size(name)==0
747                     * @param name
748                     */
749                    public void GiveDisplayName( String name) {
750                    
751                            Request request = null;
752                            try {
753                                    request = new XCallRequest(2,10);
754                            } catch (IOException e) {
755                                    e.printStackTrace();
756                                    if (skype.errorListener != null)
757                                            skype.errorListener.OnSkypeKitFatalError();
758                            }
759                            request.addParm('O',0,mObjectId);
760                            request.addParm('S',1,name);
761                            
762                            skype.XCall((XCallRequest)request);
763                    }
764                    
765                    /**
766                     *Adds or removes this Contact from the ALL_BUDDIES hardwired group. <br>
767                     * @param isMyBuddy <br> - true: add this contact to the ALL_BUDDIES group <br> - false: delete contact from the ALL_BUDDIES group <br>
768                     * @param syncAuth This argument is deprecated and should not be used. <br>
769                     */
770                    public void SetBuddyStatus( boolean isMyBuddy, boolean syncAuth) {
771                    
772                            Request request = null;
773                            try {
774                                    request = new XCallRequest(2,12);
775                            } catch (IOException e) {
776                                    e.printStackTrace();
777                                    if (skype.errorListener != null)
778                                            skype.errorListener.OnSkypeKitFatalError();
779                            }
780                            request.addParm('O',0,mObjectId);
781                            request.addParm('b',1,isMyBuddy);
782                            request.addParm('b',2,syncAuth);
783                            
784                            skype.XCall((XCallRequest)request);
785                    }
786                    
787                    /**
788                     */
789                    public enum EXTRA_AUTHREQ_FIELDS {
790                    
791                            /** send verified e-mail blob with this auth request*/
792                            SEND_VERIFIED_EMAIL(1),
793                            
794                            /** send verified company blob with this auth request*/
795                            SEND_VERIFIED_COMPANY(2);
796                            
797                            private static final Map<Integer,EXTRA_AUTHREQ_FIELDS> lookup = new HashMap<Integer,EXTRA_AUTHREQ_FIELDS>();
798                            
799                            static {
800                                    for(EXTRA_AUTHREQ_FIELDS s : EnumSet.allOf(EXTRA_AUTHREQ_FIELDS.class))
801                                            lookup.put(s.getId(), s);
802                            }
803                            
804                            private final int id;
805                            
806                            private EXTRA_AUTHREQ_FIELDS(int value) {
807                                    this.id = value;
808                            }
809                            
810                            public int getId() { return id; }
811                            
812                            public static EXTRA_AUTHREQ_FIELDS get(int code) {
813                                    return lookup.get(code);
814                            }
815                            
816                            public static EXTRA_AUTHREQ_FIELDS fromString(String s) {
817                                    for (EXTRA_AUTHREQ_FIELDS p : lookup.values()) {
818                                            if (p.toString() == s) {
819                                                    return p;
820                                            }
821                                    }
822                                    return null;
823                            }
824                    }
825                    
826                    /**
827                     *Sends a contact authorization request to this user. <br>
828                     * @param message Text that typically introduces the requesting user and details the reason for the authorization request. This text will be set as Message.P_BODY_XML property of the notification Message the remote user will receive upon getting the authortization request. While this can be the empty string, it cannot be null. <br>
829                     * @param extras_bitmask Indicates additional information to include with this authorization request: <br> - 0 (zero): do not include any additional information <br> - SEND_VERIFIED_EMAIL: include the requestor's verified e-mail address <br> - SEND_VERIFIED_COMPANY: include verified information regarding the requestor's company <br> - SEND_VERIFIED_EMAIL + SEND_VERIFIED_COMPANY: include both e-mail and company information <br>
830                     */
831                    public void SendAuthRequest( String message, int extras_bitmask) {
832                    
833                            Request request = null;
834                            try {
835                                    request = new XCallRequest(2,13);
836                            } catch (IOException e) {
837                                    e.printStackTrace();
838                                    if (skype.errorListener != null)
839                                            skype.errorListener.OnSkypeKitFatalError();
840                            }
841                            request.addParm('O',0,mObjectId);
842                            request.addParm('S',1,message);
843                            request.addParm('u',2,extras_bitmask);
844                            
845                            skype.XCall((XCallRequest)request);
846                    }
847                    
848                    /**
849                     *the contact has accepted my auth request
850                     * @return result
851                     */
852                    public boolean HasAuthorizedMe() {
853                    
854                            Request request = null;
855                            try {
856                                    request = new XCallRequest(2,14);
857                            } catch (IOException e) {
858                                    e.printStackTrace();
859                                    if (skype.errorListener != null)
860                                            skype.errorListener.OnSkypeKitFatalError();
861                            }
862                            request.addParm('O',0,mObjectId);
863                            
864                            Response r = skype.XCall((XCallRequest)request);
865                            
866                            if (r.isErrCall())
867                                    return false;
868                                    
869                            boolean result = false;
870                            result = r.GetAsBoolean(1);
871                            return result;
872                    }
873                    
874                    /**
875                     *Sets the three P_ASSIGNED_PHONEx and P_ASSIGNED_PHONEx_LABEL properties, where x reflects the value of num.  <br><br>The Skype Windows desktop client uses the following conventions when interpreting and assigning values to these properties. While your solution can assign arbitrary values to these properties, we strongly recommend using these conventions to ensure interoperability with the Skype Windows desktop client. Keep in mind that the "number" of these property pairs has no relationship to how the Skype Windows client interprets their label property value strings. For example, the Skype Windows client will interpret P_ASSIGNED_PHONE3_LABEL as "Home" if its value is the string "0".  <br><br>Label strings: <br><br>Populate the label properties with string representations of the numbers "0" through "3", rather than descriptive strings like "Home", "Mobile", and so forth. The Skype desktop clients interpret the numeric string values as: <br> - "0" (zero) - "Home" <br> - "1" (one) - "Office" <br> - "2" - "Mobile" <br> - "3" - "Other" <br><br>Keep in mind that the "number" of a property pair has no relationship to its label string. For example, the Skype Windows client will interpret P_ASSIGNED_PHONE3_LABEL as "Home" if its value is the string "0". <br><br>Phone number strings: <br><br>The Skype Windows desktop client has distinct conventions for Skype Contacts and PSTN (SkypeOut) Contacts: any or all of the property pairs can be used for Skype Contacts; P_ASSIGNED_PHONE1 cannot be used for PSTN Contacts and P_ASSIGNED_PHONE1_LABEL has special meaning for PSTN Contacts. <br>Specifically, the Skype desktop clients use P_ASSIGNED_PHONE1_LABEL as the label for a PSTN Contact's primary number (regardless of whether it's home, mobile, or office), and use P_PSTNNUMBER to hold the actual number. <br><br>
876                     * @param num The property pair being set, which must be in the range 0..3 <br>
877                     * @param label The label text for the property being set <br>
878                     * @param number The phone number for the property being set <br>
879                     */
880                    public void SetPhoneNumber( int num, String label, String number) {
881                    
882                            Request request = null;
883                            try {
884                                    request = new XCallRequest(2,15);
885                            } catch (IOException e) {
886                                    e.printStackTrace();
887                                    if (skype.errorListener != null)
888                                            skype.errorListener.OnSkypeKitFatalError();
889                            }
890                            request.addParm('O',0,mObjectId);
891                            request.addParm('u',1,num);
892                            request.addParm('S',2,label);
893                            request.addParm('S',3,number);
894                            
895                            skype.XCall((XCallRequest)request);
896                    }
897                    
898                    /**
899                     *Retrieves a dialog conversation with the Contact. <br>
900                     * @return conversation Retrieved dialog. <br>
901                     */
902                    public Conversation OpenConversation() {
903                    
904                            Request request = null;
905                            try {
906                                    request = new XCallRequest(2,17);
907                            } catch (IOException e) {
908                                    e.printStackTrace();
909                                    if (skype.errorListener != null)
910                                            skype.errorListener.OnSkypeKitFatalError();
911                            }
912                            request.addParm('O',0,mObjectId);
913                            
914                            Response r = skype.XCall((XCallRequest)request);
915                            
916                            if (r.isErrCall())
917                                    return null;
918                                    
919                            int oid = 0;
920                            Conversation conversation = null;
921                            oid = r.GetOid(1);
922                            if (oid != AbstractDecoder.NULL_VALUE) {
923                                    conversation = (Conversation)skype.factory(Conversation.moduleID(), oid, skype);
924                            }
925                            return conversation;
926                    }
927                    
928                    /**
929                    This enumerator is used by both Contact and Account objects. Thus the items here can have slightly different meaning, depending on which context you will examine their values. In case of Contact, the values apply to a user - across all the instances that user has logged in with Skype. In case of Account, the capability is that of a local, currently logged in instance of Skype client. <br><br>The values that CAPABILITY items can have are also dependant on class context. In context of Contact, a capability can be CAPABILITY_MIXED. Which in case of CAPABILITY_VIDEO, for example, would mean that the remote use has logged in with different clients, some of which support video calls and some of which don't. In context of Account - there are no mixed result. Currently logged in Skype instance either supports video or it doesn't. <br> */
930                    public enum CAPABILITY {
931                    
932                            /** For Account object, this is the same as CAPABILITY_CAN_BE_SENT_VM - it indicates that the currently logged in Skype instance supports voicemails. For Contact objects, it means that their remote system supports sending voicemails - there is no technical method for Skype to detect whether they are capable of receiving voicemails, so the assumption is that they can. <br>*/
933                            CAPABILITY_VOICEMAIL(0),
934                            
935                            /** Indicates that the contact/account has SkypeOut and is thus capable of making PSTN calls. <br>*/
936                            CAPABILITY_SKYPEOUT(1),
937                            
938                            /** Indicates that the contact/account has SkypeIn and is thus capable of answering PSTN calls. <br>*/
939                            CAPABILITY_SKYPEIN(2),
940                            
941                            /** For contacts, this is a combination of CAPABILITY_VOICEMAIL for local account (local Skype client supports sending voicemails) and CAPABILITY_VOICEMAIL of the Contact - if the contact supports sending voicemails then hopefully they can also receive them. <br>*/
942                            CAPABILITY_CAN_BE_SENT_VM(3),
943                            
944                            /** Indicates that Account/Contact supports call forwarding. <br>*/
945                            CAPABILITY_CALL_FORWARD(4),
946                            
947                            /** Indicates that Account/Contact supports call video calls. <br>*/
948                            CAPABILITY_VIDEO(5),
949                            
950                            /** In context of Contact, this indicates that the user is noticed running at least one Skype implementation that supports text messaging. Basically, it applies to a user. When applied to Account, the meaning is slightly different. In that case it indicates that currently running Skype implementation supports chat messaging. So, for Account objects, this is a node (rather than user) capability. <br>*/
951                            CAPABILITY_TEXT(6),
952                            
953                            /** Indicates that the contact/account is flagged as SkypePrime service provider. This is linked to Account class SERVICE_PROVIDER_INFO property. <br>*/
954                            CAPABILITY_SERVICE_PROVIDER(7),
955                            
956                            /** This is a legacy item, from the old times when conference calls with more than 5 people were limited to SkypePro accounts. In other words, this item is no longer relevant and will likely be removed at some point in future. <br>*/
957                            CAPABILITY_LARGE_CONFERENCE(8),
958                            
959                            /** */
960                            CAPABILITY_COMMERCIAL_CONTACT(9),
961                            
962                            /** Indicates that Account/Contact supports call transfers to PSTN numbers. <br>*/
963                            CAPABILITY_PSTN_TRANSFER(10),
964                            
965                            /** Indicates that the user has had his chat capability removed by Skype. Basically, this means that the user is reported as spammer too many times. This applies for both Contact and Account objects - which means your client can check locally, if the currently logged in user has been marked as a spammer. <br>*/
966                            CAPABILITY_TEXT_EVER(11),
967                            
968                            /** Indicates that the user (Account or Contact) has had his voice call capability removed by Skype. <br>*/
969                            CAPABILITY_VOICE_EVER(12),
970                            
971                            /** Indicates that the instance of Skype client Account/Contact is or in Contact's case has at least occasionally been flagged as a mobile device. <br>*/
972                            CAPABILITY_MOBILE_DEVICE(13),
973                            
974                            /** */
975                            CAPABILITY_PUBLIC_CONTACT(14);
976                            
977                            private static final Map<Integer,CAPABILITY> lookup = new HashMap<Integer,CAPABILITY>();
978                            
979                            static {
980                                    for(CAPABILITY s : EnumSet.allOf(CAPABILITY.class))
981                                            lookup.put(s.getId(), s);
982                            }
983                            
984                            private final int id;
985                            
986                            private CAPABILITY(int value) {
987                                    this.id = value;
988                            }
989                            
990                            public int getId() { return id; }
991                            
992                            public static CAPABILITY get(int code) {
993                                    return lookup.get(code);
994                            }
995                            
996                            public static CAPABILITY fromString(String s) {
997                                    for (CAPABILITY p : lookup.values()) {
998                                            if (p.toString() == s) {
999                                                    return p;
1000                                            }
1001                                    }
1002                                    return null;
1003                            }
1004                    }
1005                    
1006                    /**
1007                    List of possible states of each of the Contact class CAPABILITY items. <br> */
1008                    public enum CAPABILITYSTATUS {
1009                    
1010                            /** Contact does not have the capability <br>*/
1011                            NO_CAPABILITY(0),
1012                            
1013                            /** Contact has occasionally logged in with Skype client that supports the capability. For example, a contact may have Skype client on several machines, only some of which have webcam - in which case CAPABILITY_VIDEO would have its value set as CAPABILITY_MIXED. <br>*/
1014                            CAPABILITY_MIXED(1),
1015                            
1016                            /** Contact has the capability <br>*/
1017                            CAPABILITY_EXISTS(2);
1018                            
1019                            private static final Map<Integer,CAPABILITYSTATUS> lookup = new HashMap<Integer,CAPABILITYSTATUS>();
1020                            
1021                            static {
1022                                    for(CAPABILITYSTATUS s : EnumSet.allOf(CAPABILITYSTATUS.class))
1023                                            lookup.put(s.getId(), s);
1024                            }
1025                            
1026                            private final int id;
1027                            
1028                            private CAPABILITYSTATUS(int value) {
1029                                    this.id = value;
1030                            }
1031                            
1032                            public int getId() { return id; }
1033                            
1034                            public static CAPABILITYSTATUS get(int code) {
1035                                    return lookup.get(code);
1036                            }
1037                            
1038                            public static CAPABILITYSTATUS fromString(String s) {
1039                                    for (CAPABILITYSTATUS p : lookup.values()) {
1040                                            if (p.toString() == s) {
1041                                                    return p;
1042                                            }
1043                                    }
1044                                    return null;
1045                            }
1046                    }
1047                    
1048                    /**
1049                     *Retrieves a Contact.Capability value. Sets P_REFRESHING to true while querying from server. This method is functionally the same as Contact.GetCapabilityStatus except that it returns a bool value rather than Contact.CAPABILITYSTATUS <br>
1050                     * @param capability The target capability <br>
1051                     * @param queryServer <br> - true: obtains the data from the p2p network/server, and sets P_REFRESHING to true for the duration  <br> - false: obtains the data from the local client <br>
1052                     * @return result <br> - true: the Contact has the target capability through at least one of the Skype clients they have logged into. Corresponds to CAPABILITY_MIXED and CAPABILITY_EXISTS <br> - false: the Contact does not have the target capability. Corresponds to NO_CAPABILITY <br>
1053                     */
1054                    public boolean HasCapability( CAPABILITY capability, boolean queryServer) {
1055                    
1056                            Request request = null;
1057                            try {
1058                                    request = new XCallRequest(2,18);
1059                            } catch (IOException e) {
1060                                    e.printStackTrace();
1061                                    if (skype.errorListener != null)
1062                                            skype.errorListener.OnSkypeKitFatalError();
1063                            }
1064                            request.addParm('O',0,mObjectId);
1065                            request.addParm('e',1,capability.getId());
1066                            request.addParm('b',2,queryServer);
1067                            
1068                            Response r = skype.XCall((XCallRequest)request);
1069                            
1070                            if (r.isErrCall())
1071                                    return false;
1072                                    
1073                            boolean result = false;
1074                            result = r.GetAsBoolean(1);
1075                            return result;
1076                    }
1077                    
1078                    /**
1079                     *Retrieves a Contact.Capability value. Sets P_REFRESHING to true while querying from server. <br>
1080                     * @param capability The target capability, see Contact.Capability enumerator. <br>
1081                     * @param queryServer <br> - true: obtains the data from the p2p network/server, and sets P_REFRESHING to true for the duration  <br> - false: obtains the data from the local client <br>
1082                     * @return status Status of the target capability. <br>
1083                     */
1084                    public CAPABILITYSTATUS GetCapabilityStatus( CAPABILITY capability, boolean queryServer) {
1085                    
1086                            Request request = null;
1087                            try {
1088                                    request = new XCallRequest(2,19);
1089                            } catch (IOException e) {
1090                                    e.printStackTrace();
1091                                    if (skype.errorListener != null)
1092                                            skype.errorListener.OnSkypeKitFatalError();
1093                            }
1094                            request.addParm('O',0,mObjectId);
1095                            request.addParm('e',1,capability.getId());
1096                            request.addParm('b',2,queryServer);
1097                            
1098                            Response r = skype.XCall((XCallRequest)request);
1099                            
1100                            if (r.isErrCall())
1101                                    return null;
1102                                    
1103                            CAPABILITYSTATUS capabilitystatus = null;
1104                            capabilitystatus = CAPABILITYSTATUS.get(r.GetAsInt(1));
1105                            return capabilitystatus;
1106                    }
1107                    
1108                    /**
1109                     *Refreshes all properties, capabilities, and statuses associated with this Contact from p2p/CBL, and sets P_REFRESHING to true for the duration. <br>
1110                     */
1111                    public void RefreshProfile() {
1112                    
1113                            Request request = null;
1114                            try {
1115                                    request = new XCallRequest(2,20);
1116                            } catch (IOException e) {
1117                                    e.printStackTrace();
1118                                    if (skype.errorListener != null)
1119                                            skype.errorListener.OnSkypeKitFatalError();
1120                            }
1121                            request.addParm('O',0,mObjectId);
1122                            
1123                            skype.XCall((XCallRequest)request);
1124                    }
1125                    
1126            
1127            }