﻿/**
 * Copyright 2007 Fox Interactive Media
 * <DISCLAIMER HERE>
 * @fileoverview Interface for container and associated classes; everything needed to query/update MySpace API data via OpenSocial interface.
 * 
 * @author mnewbould@myspace.com (Max Newbould)
 * @author crussell@myspace.com (Chad Russell)
 */
 
 /**
 * @constructor
 * @private
 * @internal
 */
MyOpenSpace.DataMapper_ = function() {
    this.mapData[MyOpenSpace.DataMapper_.Field.PERSON] = this.mapPerson_;
    this.mapData[MyOpenSpace.DataMapper_.Field.FRIENDS] = this.mapFriends_;
    this.mapData[MyOpenSpace.DataMapper_.Field.ALBUMS] = this.mapAlbums_;
    this.mapData[MyOpenSpace.DataMapper_.Field.ALBUM] = this.mapAlbum_;
    this.mapData[MyOpenSpace.DataMapper_.Field.VIDEOS] = this.mapVideos_;
    this.mapData[MyOpenSpace.DataMapper_.Field.VIDEO] = this.mapVideo_;
    this.mapData[MyOpenSpace.DataMapper_.Field.PHOTOS] = this.mapPhotos_;
    this.mapData[MyOpenSpace.DataMapper_.Field.PHOTO] = this.mapPhoto_;
    this.mapData[MyOpenSpace.DataMapper_.Field.PERSON_APP_DATA] = this.mapPersonAppData_;
    this.mapData[MyOpenSpace.DataMapper_.Field.GLOBAL_APP_DATA] = this.mapGlobalAppData_;
}
/**
 * Defines the types of data that can be mapped
 * @static
 * @class
 * @name MyOpenSpace.DataMapper_.Field
 * @internal
 */
MyOpenSpace.DataMapper_.Field = {
    PERSON:"PERSON",
    FRIENDS:"FRIENDS",
    ALBUMS:"ALBUMS",
    ALBUM:"ALBUM",
    VIDEOS:"VIDEOS",
    VIDEO:"VIDEO",
    PHOTOS:"PHOTOS",
    PHOTO:"PHOTO",
    PERSON_APP_DATA:"PERSON_APP_DATA",
    GLOBAL_APP_DATA:"GLOBAL_APP_DATA"
};
/**
 * Maps JSON responses from the API into the various objects
 * @class
 * @name MyOpenSpace.DataMapper_
 * @private
 * @internal
 */
MyOpenSpace.DataMapper_.prototype={
    mapData:{},
    /**
     * Maps a server response into a opensocial.Collection of MyOpenSpace.Photo objects
     * @function
     * @return {opensocial.Collection}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapPhotos_: function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapPhotos_()");
        try{
            var unmapped = gadgets.JSON.parse(obj.responseText);
        }
        catch(err){
            return null;
        }
        var photos = [];
        var photo;
        var ns = MyOpenSpace.Photo.Field;

        if(unmapped.photos) {
            for(var i = 0; i < unmapped.photos.length; i++) {
                photo = new opensocial.Container.get().newPhoto();
                photo.setField_(ns.PHOTO_ID,unmapped.photos[i].id);
                photo.setField_(ns.PHOTO_URI,unmapped.photos[i].photoUri);
                photo.setField_(ns.IMAGE_URI,unmapped.photos[i].imageUri);
                photo.setField_(ns.CAPTION,unmapped.photos[i].caption);
                //photo.setField_(ns.COMMENTS_COUNT,unmapped.photos[i].commentsCount);
                photos.push(photo);
            }
        }
        
        return opensocial.Container.get().newCollection(photos, 0, unmapped.count);
    },
    
    /**
     * Maps a server response into a MyOpenSpace.Photo object
     * @function
     * @return {MyOpenSpace.Photo}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapPhoto_: function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapPhoto_()");
        var unmapped = gadgets.JSON.parse(obj.responseText);
        var photo = new opensocial.Container.get().newPhoto();
        var ns = MyOpenSpace.Photo.Field;

        if(unmapped) {
            photo.setField_(ns.PHOTO_ID,unmapped.id);
            photo.setField_(ns.PHOTO_URI,unmapped.photoUri);
            photo.setField_(ns.IMAGE_URI,unmapped.imageUri);
            photo.setField_(ns.CAPTION,unmapped.caption);
            //photo.setField_(ns.COMMENTS_COUNT,unmapped.commentsCount);
        }
        
        return photo;
    },
     mapPersonAppData_ : function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapPersonAppData_()");
        var appDataXML = obj.responseXML;
        
        if(null === appDataXML || "undefined" === typeof(appDataXML)) return null;
        
        var userCount = appDataXML.childNodes.length;
        var userNode = appDataXML.firstChild;
        var userId;
        var appDataNode;
        var appDataCount = 0;
        for (var i=0;i<userNode.childNodes.length;i++) {
            if ("userid"===userNode.childNodes[i].nodeName) 
                userId = userNode.childNodes[i].firstChild.nodeValue;
            if ("appdata"===userNode.childNodes[i].nodeName)
                appDataNode = userNode.childNodes[i];
            if ("appdatafriends"===userNode.childNodes[i].nodeName)
                appDataNode = userNode.childNodes[i];
        }
        i = 0;
        var personAppData = {};
        
        if ("appdatafriends"===appDataNode.nodeName) {
            var friendId=0;
            var friendNode;
            var friendAppDataNode;
            for (var k=0;k<appDataNode.childNodes.length;k++)
            {
                friendNode = appDataNode.childNodes[k];
                for (var m=0;m<friendNode.childNodes.length;m++)
                {
                    if ("friendid"===friendNode.childNodes[m].nodeName) {
                        friendId = friendNode.childNodes[m].firstChild.nodeValue;
                    }
                    if ("appdata"===friendNode.childNodes[m].nodeName) {
                        friendAppDataNode = friendNode.childNodes[m];
                    }
                }
                personAppData[friendId] = {};
                appDataCount = friendAppDataNode.getAttribute("count");
                for (var j=0;j<friendAppDataNode.childNodes.length;j++) {        
                    personAppData[friendId][friendAppDataNode.childNodes[j].getAttribute("name")] = friendAppDataNode.childNodes[j].getAttribute("value");
                }
            }
        } else {
            personAppData[userId] = {};
            appDataCount = appDataNode.getAttribute("count");
            for (var i=0;i<appDataNode.childNodes.length;i++) {
                if ("key"===appDataNode.childNodes[i].nodeName) {
                    personAppData[userId][appDataNode.childNodes[i].getAttribute("name")] = appDataNode.childNodes[i].getAttribute("value");
                }
            }
        } 
        return personAppData;
    },
    mapGlobalAppData_ : function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapGlobalAppData_()");
        var appDataXML = obj.responseXML;
        
        if(null === appDataXML || "undefined" === typeof(appDataXML)) return null;
        
        var userCount = appDataXML.childNodes.length;
        var userNode = appDataXML.firstChild;
        var userId;
        var appDataNode;
        for (var i=0;i<userNode.childNodes.length;i++) {
            if ("appdata"===userNode.childNodes[i].nodeName)
                appDataNode = userNode.childNodes[i];
        }
        i = 0;
        var globalAppData = {};
        for (var i=0;i<appDataNode.childNodes.length;i++) {
            if ("key"===appDataNode.childNodes[i].nodeName) {
                globalAppData[appDataNode.childNodes[i].getAttribute("name")] = appDataNode.childNodes[i].getAttribute("value");
            }
        }
       
        return globalAppData;
    },
    /**
     * Maps a server response into a opensocial.Collection of MyOpenSpace.Album objects
     * @function
     * @return {opensocial.Collection}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapAlbums_: function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapAlbums_()");
        try{
            var unmapped = gadgets.JSON.parse(obj.responseText);
        }
        catch(err){
            return null;
        }
        var albums = [];
        var album;
        var ns = MyOpenSpace.Album.Field;

        if(unmapped.albums) {
            for(var i = 0; i < unmapped.albums.length; i++) {
                album = new opensocial.Container.get().newAlbum();
                album.setField_(ns.ALBUM_ID,unmapped.albums[i].id);
                album.setField_(ns.ALBUM_URI,unmapped.albums[i].albumUri);
                album.setField_(ns.TITLE,unmapped.albums[i].title);
                album.setField_(ns.LOCATION,unmapped.albums[i].location);
                album.setField_(ns.DEFAULT_IMAGE,unmapped.albums[i].defaultImage);
                album.setField_(ns.PRIVACY,unmapped.albums[i].privacy);
                album.setField_(ns.PHOTO_COUNT,unmapped.albums[i].photoCount);
                album.setField_(ns.PHOTOS_URI,unmapped.albums[i].photosUri);
                albums.push(album);
            }
        }
        
        return opensocial.Container.get().newCollection(albums, 0, unmapped.count);
    },
    
    /**
     * Maps a server response into a MyOpenSpace.Album object
     * @function
     * @return {MyOpenSpace.Album}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapAlbum_: function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapAlbum_()");
        var unmapped = gadgets.JSON.parse(obj.responseText);
        var album = new opensocial.Container.get().newAlbum();
        var ns = MyOpenSpace.Album.Field;

        if(unmapped) {
            album.setField_(ns.ALBUM_ID,unmapped.id);
            album.setField_(ns.ALBUM_URI,unmapped.albumUri);
            album.setField_(ns.TITLE,unmapped.title);
            album.setField_(ns.LOCATION,unmapped.location);
            album.setField_(ns.DEFAULT_IMAGE,unmapped.defaultImage);
            album.setField_(ns.PRIVACY,unmapped.privacy);
            album.setField_(ns.PHOTO_COUNT,unmapped.photoCount);
            album.setField_(ns.PHOTOS_URI,unmapped.photosUri);
        }
        
        return album;
    },
    
    /**
     * Maps a server response into a opensocial.Collection of MyOpenSpace.Video objects
     * @function
     * @return {opensocial.Collection}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapVideos_: function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapVideos_()");
        try{
            var unmapped = gadgets.JSON.parse(obj.responseText);
        }
        catch(err){
            return null;
        }
        var videos = [];
        var video;
        var ns = MyOpenSpace.Video.Field;

        if(unmapped.videos) {
            for(var i = 0; i < unmapped.videos.length; i++) {
                video = new opensocial.Container.get().newVideo();
                video.setField_(ns.VIDEO_ID,unmapped.videos[i].id);
                video.setField_(ns.VIDEO_URI,unmapped.videos[i].videoUri);
                video.setField_(ns.TITLE,unmapped.videos[i].title);
                video.setField_(ns.DATE_CREATED,unmapped.videos[i].datecreated);
                video.setField_(ns.LAST_UPDATE,unmapped.videos[i].dateupdated);
                video.setField_(ns.MEDIA_TYPE,unmapped.videos[i].mediatype);
                video.setField_(ns.THUMB_URI,unmapped.videos[i].thumbnail);
                video.setField_(ns.DESCRIPTION,unmapped.videos[i].description);
                video.setField_(ns.MEDIA_STATUS,unmapped.videos[i].mediastatus);
                video.setField_(ns.RUN_TIME,unmapped.videos[i].runtime);
                video.setField_(ns.TOTAL_VIEWS,unmapped.videos[i].totalviews);
                video.setField_(ns.TOTAL_COMMENTS,unmapped.videos[i].totalcomments);
                video.setField_(ns.TOTAL_RATING,unmapped.videos[i].totalrating);
                video.setField_(ns.TOTAL_VOTES,unmapped.videos[i].totalvotes);
                video.setField_(ns.COUNTRY,unmapped.videos[i].country);
                video.setField_(ns.LANGUAGE,unmapped.videos[i].language);
                videos.push(video);
            }
        }
        
        return opensocial.Container.get().newCollection(videos, 0, unmapped.count);
    },
    
    /**
     * Maps a server response into a MyOpenSpace.Video object
     * @function
     * @return {MyOpenSpace.Video}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapVideo_: function(obj){
        myOsTrace("MyOpenSpace.DataMapper_.mapVideo_()");
        var unmapped = gadgets.JSON.parse(obj.responseText);
        var video = new opensocial.Container.get().newVideo();
        var ns = MyOpenSpace.Video.Field;

        if(unmapped) {
            video.setField_(ns.VIDEO_ID,unmapped.id);
            video.setField_(ns.VIDEO_URI,unmapped.videoUri);
            video.setField_(ns.TITLE,unmapped.title);
            video.setField_(ns.DATE_CREATED,unmapped.datecreated);
            video.setField_(ns.LAST_UPDATE,unmapped.dateupdated);
            video.setField_(ns.MEDIA_TYPE,unmapped.mediatype);
            video.setField_(ns.THUMB_URI,unmapped.thumbnail);
            video.setField_(ns.DESCRIPTION,unmapped.description);
            video.setField_(ns.MEDIA_STATUS,unmapped.mediastatus);
            video.setField_(ns.RUN_TIME,unmapped.runtime);
            video.setField_(ns.TOTAL_VIEWS,unmapped.totalviews);
            video.setField_(ns.TOTAL_COMMENTS,unmapped.totalcomments);
            video.setField_(ns.TOTAL_RATING,unmapped.totalrating);
            video.setField_(ns.TOTAL_VOTES,unmapped.totalvotes);
            video.setField_(ns.COUNTRY,unmapped.country);
            video.setField_(ns.LANGUAGE,unmapped.language);
        }
        
        return video;
    },
    
    /**
     * Maps a server response into a opensocial.Collection of MyOpenSpace.Person objects
     * @function
     * @return {opensocial.Collection}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapFriends_: function(obj){
		myOsTrace("MyOpenSpace.DataMapper_.mapFriends_()");
		try{
            var unmapped = gadgets.JSON.parse(obj.responseText);
        }
        catch(err){
            return null;
        }
        var friends = [];
        var person;
        var ns = opensocial.Person.Field;
        var mosns = MyOpenSpace.Person.Field;

        if(unmapped.friends) {
            for(var i = 0; i < unmapped.friends.length; i++) {
                person = new opensocial.Container.get().newPerson();
                person.setField_(ns.ID,""+unmapped.friends[i].userId);

                var nameParams = {};
                nameParams[opensocial.Name.Field.UNSTRUCTURED] = unmapped.friends[i].name;
                var personName = new opensocial.Container.get().newName(nameParams);
                person.setField_(ns.NAME, personName);
                
                person.setField_(ns.THUMBNAIL_URL,unmapped.friends[i].image);
                person.setField_(ns.PROFILE_URL,unmapped.friends[i].webUri);
                if("undefined" !== typeof(unmapped.friends[i].mood)) person.setField_(mosns.MOOD,unmapped.friends[i].mood);
                if("undefined" !== typeof(unmapped.friends[i].moodLastUpdated)) person.setField_(mosns.MOOD_LAST_UPDATED,unmapped.friends[i].moodLastUpdated);
                if("undefined" !== typeof(unmapped.friends[i].status)) person.setField_(mosns.STATUS,unmapped.friends[i].status);
                if("undefined" !== typeof(unmapped.friends[i].onlineNow)) person.setField_(mosns.ONLINE_NOW,unmapped.friends[i].onlineNow);
                person._type = unmapped.friends[i].type;
                friends.push(person);
            }
        }
        return opensocial.Container.get().newCollection(friends, 0, unmapped.count);
    },
    
    /**
     * Maps a server response into a MyOpenSpace.Person object
     * @function
     * @return {MyOpenSpace.Person}
     * @param {XMLHttpRequest} obj The response from the server
     * @internal
     * @private
     */
    mapPerson_: function(obj, isOwner, isViewer) {
		myOsTrace("MyOpenSpace.DataMapper_.mapPerson_()");
        var unmapped = gadgets.JSON.parse(obj.responseText);

        if(unmapped){
            var person = new opensocial.Container.get().newPerson(null, isOwner, isViewer);
            var ns = opensocial.Person.Field;
            var mosns = MyOpenSpace.Person.Field;
            
            if(unmapped.type) person._type = unmapped.type;
            else person._type = "basic";

            switch(person._type){
                case "full":
                    //BASIC
                    person.setField_(ns.ID,"" + unmapped.basicprofile.userId);
                    
                    var nameParams = {};
                    nameParams[opensocial.Name.Field.UNSTRUCTURED] = unmapped.basicprofile.name;
                    var personName = new opensocial.Container.get().newName(nameParams);
                    person.setField_(ns.NAME, personName);
                    
                    person.setField_(ns.THUMBNAIL_URL,unmapped.basicprofile.image);
                    person.setField_(ns.PROFILE_URL,unmapped.basicprofile.webUri);
                    //ns = MyOpenSpace.Person.Field;
                    
                    //FULL
                    person.setField_(mosns.CITY,unmapped.city);
                    person.setField_(mosns.REGION,unmapped.region);
                    person.setField_(mosns.POSTALCODE,unmapped.postalcode);
                    person.setField_(mosns.COUNTRY,unmapped.country);
                    person.setField_(mosns.HOMETOWN,unmapped.hometown);
                    person.setField_(ns.AGE,unmapped.age);
                    person.setField_(ns.GENDER,unmapped.gender);
                    person.setField_(mosns.CULTURE,unmapped.culture);
                    person.setField_(ns.ABOUT_ME,unmapped.aboutme);
                    person.setField_(ns.RELATIONSHIP_STATUS,unmapped.maritalstatus);
                    break;
                case "extended":
                    //BASIC
                    person.setField_(ns.ID,"" + unmapped.fullprofile.basicprofile.userId);
                    
                    var nameParams = {};
                    nameParams[opensocial.Name.Field.UNSTRUCTURED] = unmapped.fullprofile.basicprofile.name;
                    var personName = new opensocial.Container.get().newName(nameParams);
                    person.setField_(ns.NAME, personName);

                    
                    person.setField_(ns.THUMBNAIL_URL,unmapped.fullprofile.basicprofile.image);
                    person.setField_(ns.PROFILE_URL,unmapped.fullprofile.basicprofile.webUri);
                    //ns = MyOpenSpace.Person.Field;
                    
                    //FULL
                    person.setField_(mosns.CITY,unmapped.fullprofile.city);
                    person.setField_(mosns.REGION,unmapped.fullprofile.region);
                    person.setField_(mosns.POSTALCODE,unmapped.fullprofile.postalcode);
                    person.setField_(mosns.COUNTRY,unmapped.fullprofile.country);
                    person.setField_(mosns.HOMETOWN,unmapped.fullprofile.hometown);
                    person.setField_(ns.AGE,unmapped.fullprofile.age);
                    person.setField_(ns.GENDER,unmapped.fullprofile.gender);
                    person.setField_(mosns.CULTURE,unmapped.fullprofile.culture);
                    person.setField_(ns.ABOUT_ME,unmapped.fullprofile.aboutme);
                    person.setField_(ns.RELATIONSHIP_STATUS,unmapped.fullprofile.maritalstatus);
                    
                    //EXTENDED
                    person.setField_(mosns.HEADLINE,unmapped.headline);
                    person.setField_(mosns.OCCUPATION,unmapped.occupation);
                    person.setField_(mosns.DESIRE_TO_MEET,unmapped.desiretomeet);
                    person.setField_(ns.INTERESTS,unmapped.interests);
                    person.setField_(ns.MUSIC,unmapped.music);
                    person.setField_(ns.MOVIES,unmapped.movies);
                    person.setField_(ns.TV_SHOWS,unmapped.television);
                    person.setField_(ns.BOOKS,unmapped.books);
                    person.setField_(ns.HEROES,unmapped.heroes);
                    person.setField_(mosns.ZODIAC_SIGN,unmapped.zodiacsign);
                    person.setField_(mosns.MOOD,unmapped.mood);
                    person.setField_(ns.STATUS,unmapped.status);
                    break;
                case "basic":
                default:
                    //BASIC
                    person.setField_(ns.ID,"" + unmapped.userId);

                    var nameParams = {};
                    nameParams[opensocial.Name.Field.UNSTRUCTURED] = unmapped.name;
                    var personName = new opensocial.Container.get().newName(nameParams);
                    person.setField_(ns.NAME, personName);
                    person.setField_(ns.THUMBNAIL_URL,unmapped.image);
                    person.setField_(ns.PROFILE_URL,unmapped.webUri);
                    break;
            }
        }

        return person;
    }
};
