mpviewplugins/mpdetailsviewplugin/tsrc/unittest_resources/test-src/publishplayer.js
changeset 47 4cc1412daed0
parent 45 612c4815aebe
child 51 560ce2306a17
equal deleted inserted replaced
45:612c4815aebe 47:4cc1412daed0
     1 window["ovi"] = window["ovi"] ||
       
     2 {};
       
     3 ovi.player = ovi.player ||
       
     4 {};
       
     5 ovi.player.contextobject = ovi.player.contextobject ||
       
     6 {};
       
     7 
       
     8 ovi.player.contextobject.getInstance = function(config) {
       
     9     var player = {};
       
    10     player._create = function(options, handler, context) {
       
    11         var callable = (typeof handler === "function");
       
    12         if (callable) {
       
    13             handler.call(context, "CREATE_PENDING");
       
    14         }
       
    15         // TODO: add context object to player store
       
    16         // TODO: store options.miniview to be returned with view as HTML
       
    17         // TODO: store other properties of options to be returned with view as JSON
       
    18         // TODO: return uri (unique id in this player's store) in callback
       
    19     };
       
    20     player._cancel = function(options, handler, context) {
       
    21         var callable = (typeof handler === "function");
       
    22         if (callable) {
       
    23             handler.call(context, "CANCEL_PENDING");
       
    24         }
       
    25         // TODO: cancel pending tasks
       
    26         // TODO: cancel Player
       
    27     };
       
    28     player._delete = function(options, handler, context) {
       
    29         var callable = (typeof handler === "function");
       
    30         if (callable) {
       
    31             handler.call(context, "DELETE_PENDING");
       
    32         }
       
    33         // TODO: delete object defined in options.uri from store
       
    34     };
       
    35     player._edit = function(options, handler, context) {
       
    36         var callable = (typeof handler === "function");
       
    37         if (callable) {
       
    38             handler.call(context, "EDIT_PENDING");
       
    39         }
       
    40         // TODO: update object defined in options.uri
       
    41     };
       
    42     player._pick = function(options, handler, context) {
       
    43         var callable = (typeof handler === "function");
       
    44         if (callable) {
       
    45             handler.call(context, "PICK_PENDING");
       
    46         }
       
    47         // TODO: return list of all objects, or object defined in options.uri, fork with options.view
       
    48     };
       
    49     player._view = function(options, handler, context) {
       
    50         var callable = (typeof handler === "function");
       
    51         if (callable) {
       
    52             handler.call(context, "VIEW_PENDING");
       
    53         }
       
    54         // TODO: return object defined in options.uri, JSON if options.view == "none", HTML if "mini"
       
    55     };
       
    56     ovi.player._getInstance.call(player, config);
       
    57 };
       
    58 
       
    59 ovi.player.contextobject.Player = ovi.player.contextobject.getInstance;
       
    60 /*
       
    61  * Basic namespaces & common Player functions
       
    62  */
       
    63 
       
    64 
       
    65 
       
    66 window["ovi"] = window["ovi"] ||
       
    67 {};
       
    68 ovi.player = ovi.player ||
       
    69 {};
       
    70 
       
    71 
       
    72 
       
    73 /**
       
    74  * A function for creating a callback chain
       
    75  * @param {Object} options
       
    76  * @param {Object} handler
       
    77  * @param {Object} context
       
    78  * @return {Function}
       
    79  */
       
    80 ovi.player._notImplemented = function(functionId) {
       
    81     return function() {
       
    82         var status = ovi.player._status;
       
    83         handler.call(context, status["NOT_IMPLEMENTED"], null);
       
    84         handler.call(context, status[functionId + "_FAILURE"], null); // TODO: return description, too?
       
    85     };
       
    86 };
       
    87 
       
    88 
       
    89 
       
    90 /**
       
    91  * A method for returning an instance of a singleton
       
    92  * @param {Object} options A configuration object for the player
       
    93  */
       
    94 ovi.player._getInstance = function(options) {
       
    95     // TODO: store the configuration options
       
    96     return (function() {
       
    97         return (this.instance ||
       
    98         (function() {
       
    99             this.instance = {
       
   100                 // Public interface
       
   101                 cancel: (this._cancel || ovi.player._notImplemented("CANCEL")),
       
   102                 create: (this._create || ovi.player._notImplemented("CREATE")),
       
   103                 "delete": (this._delete || ovi.player._notImplemented("DELETE")), // delete is a keyword
       
   104                 edit: (this._edit || ovi.player._notImplemented("EDIT")),
       
   105                 pick: (this._pick || ovi.player._notImplemented("PICK")),
       
   106                 show: (this._view || ovi.player._notImplemented("VIEW")), // show is the same function as view, included in API for compatibility
       
   107                 sync: (this._sync || ovi.player._notImplemented("SYNC")),
       
   108                 view: (this._view || ovi.player._notImplemented("VIEW"))
       
   109             };
       
   110             return this.instance;
       
   111         }()));
       
   112     }());
       
   113 };
       
   114 
       
   115 
       
   116 
       
   117 ovi.player._status = {
       
   118     USER_CANCEL: "USER_CANCEL",
       
   119     
       
   120     CANCEL_PENDING: "CANCEL_PENDING",
       
   121     CANCEL_FAILURE: "CANCEL_FAILURE",
       
   122     CANCEL_SUCCESS: "CANCEL_SUCCESS",
       
   123     
       
   124     CREATE_PENDING: "CREATE_PENDING",
       
   125     CREATE_FAILURE: "CREATE_FAILURE",
       
   126     CREATE_SUCCESS: "CREATE_SUCCESS",
       
   127     
       
   128     DELETE_PENDING: "DELETE_PENDING",
       
   129     DELETE_FAILURE: "DELETE_FAILURE",
       
   130     DELETE_SUCCESS: "DELETE_SUCCESS",
       
   131     
       
   132     EDIT_PENDING: "EDIT_PENDING",
       
   133     EDIT_FAILURE: "EDIT_FAILURE",
       
   134     EDIT_SUCCESS: "EDIT_SUCCESS",
       
   135     
       
   136     PICK_PENDING: "PICK_PENDING",
       
   137     PICK_FAILURE: "PICK_FAILURE",
       
   138     PICK_SUCCESS: "PICK_SUCCESS",
       
   139     
       
   140     SYNC_PENDING: "SYNC_PENDING",
       
   141     SYNC_FAILURE: "SYNC_FAILURE",
       
   142     SYNC_SUCCESS: "SYNC_SUCCESS",
       
   143     SYNC_CONNECT_PENDING: "SYNC_CONNECT_PENDING",
       
   144     SYNC_CONNECT_FAILED: "SYNC_CONNECT_FAILED",
       
   145     SYNC_CONNECT_SUCCEEDED: "SYNC_CONNECT_SUCCEEDED",
       
   146     SYNC_LOGIN_PENDING: "SYNC_LOGIN_PENDING",
       
   147     SYNC_LOGIN_FAILED: "SYNC_LOGIN_FAILED",
       
   148     SYNC_LOGIN_SUCCEEDED: "SYNC_LOGIN_SUCCEEDED",
       
   149     SYNC_UPDATE_PENDING: "SYNC_UPDATE_PENDING",
       
   150     SYNC_UPDATE_FAILED: "SYNC_UPDATE_FAILED",
       
   151     SYNC_UPDATE_SUCCEEDED: "SYNC_UPDATE_SUCCEEDED",
       
   152     
       
   153     VIEW_PENDING: "VIEW_PENDING",
       
   154     VIEW_FAILURE: "VIEW_FAILURE",
       
   155     VIEW_SUCCESS: "VIEW_SUCCESS",
       
   156     
       
   157     NOT_IMPLEMENTED: "NOT_IMPLEMENTED"
       
   158 };
       
   159 window["ovi"] = window["ovi"] ||
       
   160 {};
       
   161 ovi.player = ovi.player ||
       
   162 {};
       
   163 ovi.player.publish = ovi.player.publish ||
       
   164 {};
       
   165 
       
   166 ovi.player.publish.getInstance = function(config) {
       
   167     var player = {};
       
   168     player._create = function(options, handler, context) {
       
   169         var callable = (typeof handler === "function");
       
   170         if (callable) {
       
   171             handler.call(context, "CREATE_PENDING");
       
   172         }
       
   173         // TODO: create UI
       
   174         // TODO: get the sub-players, sync them
       
   175     };
       
   176     player._cancel = function(options, handler, context) {
       
   177         var callable = (typeof handler === "function");
       
   178         if (callable) {
       
   179             handler.call(context, "CANCEL_PENDING");
       
   180         }
       
   181         // TODO: cancel sub-players
       
   182         // TODO: cancel pending tasks
       
   183         // TODO: cancel Player
       
   184     };
       
   185     ovi.player._getInstance.call(player, config);
       
   186 };
       
   187 
       
   188 ovi.player.publish.Player = ovi.player.publish.getInstance;
       
   189 window["ovi"] = (window["ovi"] || {});
       
   190 ovi.player = (ovi.player || {});
       
   191 ovi.player.snc = (ovi.player.snc || {});
       
   192 ovi.player.snc.engine = (ovi.player.snc.engine || {});
       
   193 
       
   194 
       
   195 (function(){
       
   196 
       
   197     var engine = ovi.player.snc.engine;
       
   198 	
       
   199 	
       
   200 	engine.status = {
       
   201 		SUCCESS : "SUCCESS",
       
   202 		FAILED : "FAILED",
       
   203 	}
       
   204 	
       
   205 	
       
   206 	var _callback = function(status, data, callback, context) {
       
   207         if (typeof callback == "function") {
       
   208             callback.call(context, status, data);
       
   209         }
       
   210 	}
       
   211     
       
   212     // External functions	
       
   213     
       
   214     /**
       
   215      * Publish the given object to the social networks.
       
   216      * @param {Object} object Published data
       
   217      * @param {String} object.text Free text
       
   218      * @param {String} object.context.artist Artist name
       
   219      * @param {String} object.context.title Song title
       
   220      * @param {Array} object.networks Array of social networks ids where to publish
       
   221      * @param {Object} [callback] Called when publish is ready.
       
   222      * @param {Object} [context]
       
   223      */
       
   224     engine.publish = function(data, callback, context){
       
   225         
       
   226         // Just concatenate some status text from received data
       
   227         var status = data.text;
       
   228         
       
   229 		// Add attached objects (temporarily just append to end of text)
       
   230         // TODO : object.type == "URI" ... etc., add as attachment when supported by SNC 		
       
   231         if (typeof data.object != "undefined") {
       
   232 	         // Get URL to song before publishing and to status text
       
   233             var link = data.object.content;
       
   234             if (link.length > 0) {
       
   235                 status += " - " + link;
       
   236             }
       
   237         }
       
   238 		 
       
   239         // Update to services 		
       
   240         ovi.activities.updateStatus(status, {networkId: data.networks }, function(response){
       
   241             
       
   242 			if (response.status == "success") {
       
   243                 _callback(engine.status.SUCCESS, null, callback, context);
       
   244 			}
       
   245 			else {
       
   246 				// TODO : Implement finer error handling
       
   247 				_callback(engine.status.FAILED, { message : "Status update failed" }, callback, context);
       
   248 			}										
       
   249         });
       
   250     }
       
   251 
       
   252 	/**
       
   253 	 * 
       
   254 	 * @param {Object} data
       
   255 	 * @param {Object} callback
       
   256 	 * @param {Object} context
       
   257 	 */
       
   258     engine.cancelPublish = function(data, callback, context){
       
   259 		_callback(engine.status.SUCCESS, null, callback, context);
       
   260     }
       
   261     
       
   262 	
       
   263 	/**
       
   264 	 * Reload social networks from SNC backend to the local store. Use getServices() to retrieve the 
       
   265 	 * list of loaded services.
       
   266 	 * @param {Object} options Object containing Noa account information. Can be user, password or already
       
   267 	 * autheticated session token to be used. { username : "", password : "" } or { token : "" }
       
   268 	 * @param {Object} callback
       
   269 	 * @param {Object} context
       
   270 	 */
       
   271     engine.sync = function(options, callback, context) {
       
   272 
       
   273         // TODO : Seperate init and login from sync (we need both for publish also...)
       
   274 
       
   275         // Do service didscovery
       
   276 		
       
   277         // 1. Init APIs
       
   278         requests.initOviApi(function(response){
       
   279         
       
   280 		    if(response.status != engine.status.SUCCESS) {
       
   281 				_callback(engine.status.FAILED, response.data, callback, context);
       
   282 				return;
       
   283 			}
       
   284 		
       
   285             // 2. Login noa     
       
   286             requests.noaLogin(options, function(response){
       
   287 
       
   288 	            if(response.status != engine.status.SUCCESS) {
       
   289 	                _callback(engine.status.FAILED, { message: response.message }, callback, context);
       
   290 					return;
       
   291 	            }
       
   292             
       
   293                 // 3. Service discover
       
   294                 requests.discover(function(response){
       
   295 
       
   296                     // Store to player store
       
   297 					store.clear();
       
   298 					store.append(response.networks);
       
   299 					store.commit(); 
       
   300 					
       
   301 					// Callback function
       
   302 					if (response.status == engine.status.SUCCESS) {
       
   303                         _callback(engine.status.OK, { networks: response.networks }, callback, context);	
       
   304 					}
       
   305 					else {
       
   306 						_callback(engine.status.FAILED, { message: response.message }, callback, context);
       
   307 					}					
       
   308                 });
       
   309             });            
       
   310         });
       
   311     }		
       
   312 	
       
   313 	/**
       
   314 	 * Get list of services (social networks). Data is loaded from local 
       
   315 	 * player store. To synchronize data social networks from SNC call sync().
       
   316 	 */
       
   317 	engine.getServices = function() {
       
   318 		// Get list of services from store
       
   319 		return store.getList();
       
   320 	}
       
   321 	
       
   322 	/**
       
   323 	 * Mark service as selected / unselected. Saves the selection to the persistent 
       
   324 	 * local storage to save data over sessions.
       
   325 	 * @param {Object} id
       
   326 	 * @param {Object} enable
       
   327 	 */
       
   328 	engine.selectService = function(id, enable) {
       
   329 		// Select / unselect service in player store
       
   330 		store.select(id, enable);		
       
   331 	}
       
   332 		
       
   333 	// Player store	
       
   334     var STORE_KEY_SERVICES = "ovi.player.snc.services";
       
   335     var STORE_KEY_SELECTED = "ovi.player.snc.services.selected";	
       
   336 	
       
   337 	/**
       
   338 	 * Player store implementation. Persists the social networks (services) and selections 
       
   339 	 * to the HTML5 local storage, which provides over sessions caching.
       
   340 	 */
       
   341 	var store = {
       
   342 
       
   343 		_services : {},
       
   344 		_selected : {},
       
   345 				
       
   346         /**
       
   347          * Add new server or services to the store.
       
   348          * @param {Object} service
       
   349          */
       
   350 		append : function(service) {
       
   351 			if (service.length) {
       
   352 	            for(var i=0; i < service.length; i++) {
       
   353 	                var s = service[i];
       
   354 	                this._services[s.id] = s;      
       
   355 	            }
       
   356 			} else {
       
   357 				this._services[service.id] = service;
       
   358 			}
       
   359 		},
       
   360 		
       
   361 		/**
       
   362 		 * Mark service selected or unselected in the store. Also commits changes in 
       
   363 		 * selections to the store.
       
   364 		 * @param {Object} id
       
   365 		 * @param {Object} enable
       
   366 		 */
       
   367 		select : function(id, enable) {
       
   368 			this._selected[id] = enable;
       
   369 			localStorage.setItem(STORE_KEY_SELECTED, JSON.stringify(this._selected));
       
   370 		},
       
   371 		
       
   372 		/**
       
   373 		 * Clear services.
       
   374 		 */
       
   375 	    clear : function() {
       
   376 	   	    this._services = {};
       
   377 	    },
       
   378 		
       
   379 		/**
       
   380 		 * Get list (array) of services in the store.
       
   381 		 */
       
   382 		getList : function() {
       
   383 			// Convert to array
       
   384 			var res = [];
       
   385 			for(var o in this._services) {				
       
   386 				var serv = this._services[o];
       
   387 				serv.selected = typeof this._selected[o] != "undefined" ? this._selected[o] : false;
       
   388 				res.push(serv);
       
   389 			}			
       
   390 			return res;
       
   391 		},
       
   392 		
       
   393 		/**
       
   394 		 * Commit services to the store.
       
   395 		 */
       
   396 		commit : function() {
       
   397 			localStorage.setItem(STORE_KEY_SERVICES, JSON.stringify(this._services));
       
   398 		},
       
   399 		
       
   400 		/**
       
   401 		 * Retrieve services and selections in the store.
       
   402 		 */
       
   403 		load : function() {
       
   404 			this._services = JSON.parse(localStorage.getItem(STORE_KEY_SERVICES));
       
   405 			this._selected = JSON.parse(localStorage.getItem(STORE_KEY_SELECTED));
       
   406 
       
   407 			if (this._services == null) this._services = {};
       
   408 			if (this._selected == null) this._selected = {};			
       
   409 		}
       
   410 	}
       
   411 		
       
   412 	
       
   413     // SNC Request implementation
       
   414     var requests = {
       
   415     
       
   416         /**
       
   417          *
       
   418          * @param {Object} callback
       
   419          */
       
   420         initOviApi: function(callback){
       
   421             var myincludes = "ovi.auth.noa_login, ovi.api.snc, ovi.api.activities, ovi.net.xss";
       
   422             ovi.onReady = function(libs){
       
   423                 if (ovi.testIfLoaded(myincludes, libs)) {
       
   424                 
       
   425                     // Successful, set environment for NCIM              
       
   426                     ovi.config.setenv("st-account", "delegate");
       
   427                     
       
   428                     // Allow cross-domain scripting
       
   429                     function xssInitCallback(data){
       
   430                         if (data.event === "InitializeOk") {
       
   431                             callback( { status : engine.status.SUCCESS });
       
   432                         }
       
   433                     }
       
   434                     
       
   435                     ovi.net.XssInit({
       
   436                         back_url: "http://spb.ci.wipsl.com/ovi-api/js/ovi/net/",
       
   437                         callback: xssInitCallback
       
   438                     });
       
   439                     
       
   440                 }
       
   441             }
       
   442             
       
   443             ovi.include(myincludes);
       
   444         },
       
   445         
       
   446         /**
       
   447          *
       
   448          * @param {Object} callback
       
   449          */
       
   450         noaLogin: function(options, callback){
       
   451 			
       
   452 			var noa = {};			
       
   453 			if (typeof options.token != "undefined") {   // This propably is not supported yet..
       
   454 				noa = { token : options.token };
       
   455 			}
       
   456 			else {
       
   457 				noa = { username : options.username, password : options.password };
       
   458 			}
       
   459 			
       
   460 			// Login
       
   461             ovi.noa.login(noa, function(state){
       
   462 				            
       
   463                 // Callback
       
   464                 if (state.status == "success") {
       
   465                     callback( {
       
   466 						status: engine.status.SUCCESS
       
   467                     } );
       
   468                 }
       
   469                 else {
       
   470 					callback( {
       
   471 						status: engine.status.FAILED,
       
   472 						message: "NOA login failed - " + state.statusCode + " - " + state.status
       
   473 					} );
       
   474                 }
       
   475             });
       
   476         },
       
   477         
       
   478         /**
       
   479          *
       
   480          * @param {Object} callback
       
   481          */
       
   482         discover: function(callback){
       
   483         
       
   484             // Discover service available
       
   485             ovi.snc.discoverSocialNetworks(function(response){
       
   486             
       
   487                 if (response.status != "success") {
       
   488                     callback( {
       
   489 						status: engine.status.FAILED,
       
   490 						message : "Service discovery failed - " + response.statusCode + " - " + response.responseText 
       
   491                     } );
       
   492                     return;
       
   493                 }
       
   494 				
       
   495                 var netw = response.data.network;
       
   496                 
       
   497                 // And get activated
       
   498                 ovi.snc.getActivatedSocialNetworks(function(response){                    
       
   499 
       
   500                     if (response.status != "success") {
       
   501 	                    callback( {
       
   502 	                        status: engine.status.FAILED,
       
   503 	                        message : "Service discovery failed - " + response.statusCode + " - " + response.responseText 
       
   504 	                    } );
       
   505 												
       
   506                         return;
       
   507                     }
       
   508 					else if (response.statusCode == 204) { // Not an error, no active networks
       
   509                         callback( {
       
   510                             status: engine.status.SUCCESS,
       
   511                             networks : [] 
       
   512                         } );
       
   513 						
       
   514 						return;
       
   515 					}
       
   516                     
       
   517 					var active = response.data.network;
       
   518                     
       
   519                     // Now we have finally the service discovery ready, create final response										
       
   520 					// Remove all not-active networks from supported networks					
       
   521                     var results = [];					
       
   522 					for(var i=0; i < netw.length; i++) {
       
   523 						var id = netw[i].id;
       
   524 						
       
   525 						for(var j=0; j < active.length; j++) {
       
   526 							if (active[j].id == id) {								
       
   527 								// We have a winner
       
   528 								results.push({ name : netw[i].name, id : netw[i].id, maxTextInput : netw[i].maxTextInput });
       
   529 								break;
       
   530 							}
       
   531 						}
       
   532 					}					
       
   533                     
       
   534                     callback( { 
       
   535 					   status: engine.status.SUCCESS, 
       
   536 					   networks : results 
       
   537                     } );                    
       
   538                 });
       
   539             });
       
   540         }
       
   541     }
       
   542     
       
   543 	// Restore data from store
       
   544     store.load();
       
   545     
       
   546 })();
       
   547 // Create needed namespace ovi.player.share.ui
       
   548 window["ovi"] = window["ovi"] ||
       
   549 {};
       
   550 ovi.player = ovi.player ||
       
   551 {};
       
   552 ovi.player.share = ovi.player.share ||
       
   553 {};
       
   554 ovi.player.share.ui = ovi.player.share.ui ||
       
   555 {};
       
   556 
       
   557 /**
       
   558  * TODO
       
   559  * 
       
   560  * This API tries to imitate medos framework UI controls for future compability.
       
   561  * @param {Object} params
       
   562  * @param {Object} target
       
   563  */
       
   564 ovi.player.share.ui.Button = function(params, target) {
       
   565     
       
   566 	var CLICK_EVENT = "selected";
       
   567 	var that = this;
       
   568 
       
   569     function createHtml() {
       
   570 	    var template = '<button class="ovi_Button ovi_unselectable ovi_clip">' +
       
   571 	       params.text + '</button>';
       
   572 	
       
   573 	    var node = document.createElement("div");  // Do we need this ??
       
   574 	    node.innerHTML = template;
       
   575 		return node;		
       
   576 	}
       
   577 
       
   578     var _root = createHtml();
       
   579 	var _button = _root.firstChild;
       
   580  
       
   581     target.appendChild(_root);
       
   582 	
       
   583 	// Interface functions
       
   584 	this.addEventHandler = function(event, callback) {
       
   585 		// selected = click (comes from medos...)		
       
   586 		if (event == CLICK_EVENT) {
       
   587             _root.addEventListener("click", function(e) { callback.call(that, e); }, that);	
       
   588 		}		 
       
   589 	} 	
       
   590 		
       
   591     this.setProperty = function(name, value) {
       
   592 		_button[name] = value;
       
   593 	}
       
   594 	
       
   595     this.getProperty = function(name) {
       
   596         return _button[name];
       
   597     }	
       
   598 }
       
   599 // Create needed namespace ovi.player.share.ui
       
   600 window["ovi"] = window["ovi"] ||
       
   601 {};
       
   602 ovi.player = ovi.player ||
       
   603 {};
       
   604 ovi.player.share = ovi.player.share ||
       
   605 {};
       
   606 ovi.player.share.ui = ovi.player.share.ui ||
       
   607 {};
       
   608 
       
   609 /**
       
   610  * Checkbox UI control implementation. TODO
       
   611  * 
       
   612  * This API tries to imitate medos framework UI controls for future compability.
       
   613  * @param {Object} params
       
   614  * @param {Object} target
       
   615  */
       
   616 ovi.player.share.ui.CheckBox = function(params, target) {
       
   617     
       
   618 	var that = this;
       
   619 
       
   620     function createHtml() {
       
   621 		      
       
   622         var template = '<div class="ovi_CheckBox ovi_unselectable ovi_clip">' +
       
   623 		                  '<input type="checkbox"></input>' +
       
   624 		                  '<span data-bind-text="label">' + params.label + '</span>' +
       
   625 					   '</div>';
       
   626 		
       
   627 	    var node = document.createElement("div");  // Do we need this ??
       
   628 	    node.innerHTML = template;
       
   629 		return node;		
       
   630 	}
       
   631 
       
   632     var _root = createHtml();
       
   633 	var _checkBox = _root.firstChild.firstChild;
       
   634  
       
   635     target.appendChild(_root);	
       
   636 	
       
   637     this.setProperty = function(name, value) {
       
   638 		
       
   639 		if (name == "selected") { // Use medos property name mappings
       
   640             _checkBox["checked"] = value;	
       
   641 		} 
       
   642 		else {
       
   643 			_checkBox = value;
       
   644 		}        
       
   645     }
       
   646 	
       
   647 	this.getProperty = function(name) {
       
   648 		if (name == "selected") {
       
   649 			return _checkBox["checked"];
       
   650 		}
       
   651 		return _checkBox[name];
       
   652 	}
       
   653 	
       
   654 	for(var v in params) {
       
   655 		this.setProperty(v, params[v]);
       
   656 	}
       
   657 }
       
   658 // Create needed namespace ovi.player.share.ui
       
   659 window["ovi"] = window["ovi"] ||
       
   660 {};
       
   661 ovi.player = ovi.player ||
       
   662 {};
       
   663 
       
   664 
       
   665 /**
       
   666  * Context object player poc implementation
       
   667  */
       
   668 ovi.player.contextobject = ovi.player.contextobject ||
       
   669 {};
       
   670 
       
   671 
       
   672 ovi.player.contextobject.Player = function() {
       
   673 	
       
   674 	var targetNS = this;	
       
   675 	targetNS.create = function(params) {
       
   676 		targetNS.object = params;		
       
   677 	}
       
   678 }
       
   679 
       
   680 
       
   681 
       
   682 /**
       
   683  * Publish player poc implementation 
       
   684  */
       
   685 ovi.player.publish = ovi.player.publish ||
       
   686 {};
       
   687 
       
   688 // Extend the namespace
       
   689 ovi.player.publish.Player = function(params) {
       
   690 
       
   691     // TODO : MAKE THIS SINGLETON SOMEHOW ??
       
   692     var targetNS = this;    
       
   693 
       
   694     // Utils
       
   695     var _id = function(id) {
       
   696         return document.getElementById(id);
       
   697     };
       
   698 	
       
   699     var _addClass = function(target, className) {
       
   700         var classes = target.className;
       
   701         if (!classes.match(new RegExp("\\b" + className + "\\b"))) {
       
   702             if (classes != "" && classes.substr(-1) != " ") {
       
   703                 target.className += " ";
       
   704             }
       
   705             target.className += className;
       
   706         }
       
   707     };
       
   708     var _removeClass = function(target, className) {
       
   709         target.className = target.className.replace(new RegExp("\\b" + className + "\\b", "g"), "");
       
   710         //TODO: clean extra spaces?
       
   711     
       
   712     };
       
   713     var _toggleClass = function(target, className) {
       
   714         if (target.className.indexOf(className) == -1) {
       
   715             _addClass(target, className);
       
   716             return true;
       
   717         } else {
       
   718             _removeClass(target, className);
       
   719             return false;
       
   720         }
       
   721         
       
   722     };
       
   723     
       
   724     
       
   725     
       
   726     /**
       
   727      * "State engine"
       
   728      */
       
   729     var _state = {
       
   730         visible: false,
       
   731         services: {}
       
   732     };
       
   733     
       
   734     
       
   735     
       
   736     /**
       
   737      * HTML templates for ui
       
   738      */
       
   739     var _templates = {
       
   740         // TODO: localization
       
   741         "share.ui": '<div class="player">\
       
   742 			<div class="panel header">Publish</div>\
       
   743 			<div class="panel panel-message">\
       
   744 				<div class="info hidden" id="comment-limit"><span id="comment-length">0</span>/<span id="comment-maxlength">0</span></div>\
       
   745 				<div class="comment" id="comment-area">\
       
   746 					<div class="hint">Write message here</div>\
       
   747 					<textarea id="message"></textarea>\
       
   748 				</div>\
       
   749 				<hr/><div class="info" id="shared-object"></div><hr/>\
       
   750 			</div>\
       
   751 			<div class="panel networks-panel"><ul class="list checked" id="available-services"></ul></div>\
       
   752 			<div class="panel panel-buttons">\
       
   753 				<ul class="list button-bar">\
       
   754 					<li id="action-ok" class="disabled"><span>OK</span></li>\
       
   755 					<li id="action-cancel"><span>Cancel</span></li>\
       
   756 				</ul>\
       
   757 			</div>\
       
   758 		</div>'
       
   759     };
       
   760     
       
   761     
       
   762     
       
   763     /**
       
   764      * Generic callback invoker
       
   765      *
       
   766      * @param {Object} notification
       
   767      * @param {Object} data
       
   768      * @param {Object} callback
       
   769      * @param {Object} context
       
   770      */
       
   771     var _callback = function(notification, data, callback, context) {
       
   772         if (typeof callback == "function") {
       
   773             callback.call(context, notification, data);
       
   774         }
       
   775     };
       
   776     
       
   777     
       
   778     
       
   779     /**
       
   780      * status messages
       
   781      */
       
   782     var _status = {
       
   783     
       
   784         show: "SHOW",
       
   785         show_ok: "SHOW_SUCCEEDED",
       
   786         show_fail: "SHOW_FAILED",
       
   787         
       
   788         updateobject: "UPDATEOBJECT",
       
   789         updateobject_ok: "UPDATEOBJECT_SUCCEEDED",
       
   790         updateobject_fail: "UPDATEOBJECT_FAILED",
       
   791         
       
   792         updateservices: "UPDATESERVICES",
       
   793         updateservices_ok: "UPDATESERVICES_SUCCEEDED",
       
   794         updateservices_fail: "UPDATESERVICES_FAILED",
       
   795 		updateservices_nonetworks : "UPDATESERVICES_NONETWORKS"
       
   796     
       
   797     };
       
   798     
       
   799     
       
   800     
       
   801     /**
       
   802      * Invokes the ui for the player
       
   803      *
       
   804      * @param {Object} [options]
       
   805      * @param {Object} [options.target] the dom node or id where the ui should be inserted
       
   806      * @param {Object} [options.template] the html for the ui
       
   807      * @param {Object} [callback]
       
   808      * @param {Object} [context]
       
   809      */
       
   810     var _show = function(options, callback, context) {
       
   811     
       
   812         var target = (options && options.target) || _id("ovi.player.share.ui"), template = (options && options.template) || _templates["share.ui"];
       
   813 
       
   814         // Find target node if id was given
       
   815         if (typeof target == "string") {
       
   816             target = _id(_target);
       
   817         }
       
   818         if (target) {
       
   819             if (template) {
       
   820                 if (_state.visible && target.innerHTML.indexOf('"player"') >= 0) {
       
   821                     // _show was already called earlier, and player is shown
       
   822                     _callback(_status.show, {
       
   823                         message: "Player is already visible"
       
   824                     }, callback, context);
       
   825                 } else {
       
   826                     target.innerHTML = template;
       
   827                     
       
   828                     // add handler for textarea
       
   829                     var message = _id("message");
       
   830                     _id("message").onkeyup = _handleMessageChange;
       
   831                     message.style.backgroundColor = "transparent";
       
   832                     
       
   833                     // add handlers for buttons
       
   834                     _id("action-ok").onclick = _handleSubmit;
       
   835                     _id("action-cancel").onclick = _handleSubmit;
       
   836                     
       
   837                     // Update state
       
   838                     _state.visible = true;
       
   839                     _callback(_status.show_ok, null, callback, context);
       
   840                 }
       
   841             } else {
       
   842                 _callback(_status.show_fail, {
       
   843                     message: "Template not found",
       
   844                     data: {
       
   845                         template: template
       
   846                     }
       
   847                 }, callback, context);
       
   848             }
       
   849         } else {
       
   850             _callback(_status.show_fail, {
       
   851                 message: "Target container not found",
       
   852                 data: {
       
   853                     target: target
       
   854                 }
       
   855             }, callback, context);
       
   856         }
       
   857 		
       
   858 		onResize();   // Initial resize
       
   859 		
       
   860 		// If we would like to show the services stored in local storage, uncommenting the following would do 
       
   861 		// the job..
       
   862 		/*
       
   863 		var services = ovi.player.share.engine.getServices();
       
   864 		targetNS.updateServices(services);*/ 		
       
   865     };
       
   866     
       
   867     /**
       
   868      * Removes all the handlers from the ui and the ui
       
   869      *
       
   870      * @param {Object} options
       
   871      * @param {Object} callback
       
   872      * @param {Object} context
       
   873      */
       
   874     var _teardown = function(options, callback, context) {
       
   875         //TODO: clear handlers
       
   876         //TODO: destroy html
       
   877         //TODO: update status
       
   878     };
       
   879 
       
   880     
       
   881     var _updateServices = function(data, callback, context) {
       
   882     
       
   883         var target = _id("available-services");
       
   884         
       
   885         if (target) {
       
   886             if (data.length) {
       
   887                 var listToCheck = [], i;
       
   888                 // TODO: add loading animation?
       
   889                 for (i = 0; i < data.length; i++) {
       
   890                     var id = data[i].id, label = data[i].name;
       
   891                     if (id && label) {
       
   892                         id = "service-" + id;
       
   893                         listToCheck.push(id);
       
   894                         if (!_id(id)) {
       
   895                             // We don't have the network in our list yet, create one
       
   896                             var item = document.createElement("LI"), checkbox = document.createElement("SPAN");
       
   897                             checkbox.setAttribute("class", "checkbox");
       
   898                             checkbox.appendChild(document.createTextNode(label));
       
   899                             item.appendChild(checkbox);
       
   900                             item.setAttribute("id", id);
       
   901                             item.onclick = _handleServiceListClick;
       
   902                             target.appendChild(item);
       
   903                             // store object to the state
       
   904 							if (data[i].selected) {
       
   905                                 data[i].checked = _toggleClass(item, "checked");
       
   906 							}							
       
   907                             _state.services[id] = data[i];
       
   908                         }
       
   909                     } else {
       
   910                         _callback(_status.updateservices, {
       
   911                             message: "Service object formatted badly",
       
   912                             data: data[i]
       
   913                         }, callback, context);
       
   914                     }
       
   915                 }
       
   916                 //make a searchable string
       
   917                 listToCheck = listToCheck.join();
       
   918                 //remove obsolete networks
       
   919                 for (i = 0; i < target.childNodes.length; i++) {
       
   920                     var node = target.childNodes[i], id = node.getAttribute("id");
       
   921                     if (listToCheck.indexOf(id) == -1) {
       
   922                         node.onclick = null;
       
   923                         target.removeChild(node);
       
   924                     }
       
   925                     // TODO: update _state?
       
   926                 }
       
   927 				_updateServiceLimits();
       
   928                 _callback(_status.updateservices_ok, null, callback, context);				
       
   929             } else {
       
   930                 _callback(_status.updateservices_fail, {
       
   931                     message: "Received data was not an array",
       
   932                     data: data
       
   933                 }, callback, context);
       
   934             }
       
   935         } else {
       
   936             _callback(_status.updateservices_fail, {
       
   937                 message: "Target container not found"
       
   938             }, callback, context);
       
   939         }
       
   940     };
       
   941     
       
   942     /**
       
   943      * Handler for message changes
       
   944      * @param {Object} e
       
   945      */
       
   946     var _handleMessageChange = function(e) {
       
   947         _id("comment-length").innerHTML = this.value.length;
       
   948         _checkMessageLength();
       
   949     }
       
   950     
       
   951     
       
   952     
       
   953     /**
       
   954      * Handler for service selection
       
   955      * @param {Object} e
       
   956      */
       
   957     var _handleServiceListClick = function(e) {
       
   958         _state.services[this.id].checked = _toggleClass(this, "checked");
       
   959 		ovi.player.snc.engine.selectService(_state.services[this.id].id, _state.services[this.id].checked);
       
   960         _updateServiceLimits();
       
   961     };
       
   962     
       
   963     
       
   964     
       
   965     /**
       
   966      * Check limits and if the OK button can be clicked
       
   967      */
       
   968     var _updateServiceLimits = function() {
       
   969         var bigNumber = 9999999, maxTextInput = bigNumber, min = Math.min, services = _state.services, service;
       
   970         for (sid in services) {
       
   971             service = services[sid];
       
   972             if (service.checked && service.maxTextInput && service.maxTextInput > 0) {
       
   973                 maxTextInput = min(maxTextInput, service.maxTextInput);
       
   974             }
       
   975         }
       
   976 		
       
   977         if (maxTextInput < bigNumber) {
       
   978             // Reduce the link and context reserved size from input (data that will be allocated 
       
   979 			// from maxTextInput for context)
       
   980 			var contextData = _state.contextPlayer.object.data;
       
   981             maxTextInput -= contextData.object.reservedLength;
       
   982 			     			
       
   983             _id("comment-maxlength").innerHTML = maxTextInput;
       
   984             _removeClass(_id("comment-limit"), "hidden");
       
   985             //TODO: alter size of elements to make space for the limit?
       
   986         } else {
       
   987             _id("comment-maxlength").innerHTML = maxTextInput;
       
   988             _addClass(_id("comment-limit"), "hidden");
       
   989         }
       
   990         _checkMessageLength();
       
   991     };
       
   992     
       
   993     
       
   994     
       
   995     var _checkMessageLength = function() {
       
   996         var length = parseInt(_id("comment-length").innerHTML), maxLength = parseInt(_id("comment-maxlength").innerHTML), message = _id("message");
       
   997         if (length == 0) {
       
   998             message.style.backgroundColor = "transparent";
       
   999         } else {
       
  1000             message.style.backgroundColor = "";
       
  1001         }
       
  1002         if ((maxLength > 0) && (length > maxLength)) {
       
  1003             _addClass(_id("comment-limit"), "error");
       
  1004             _addClass(message, "error");
       
  1005         } else {
       
  1006             _removeClass(_id("comment-limit"), "error");
       
  1007             _removeClass(message, "error");
       
  1008         }
       
  1009         _updateActions();
       
  1010     };
       
  1011     
       
  1012     
       
  1013     
       
  1014     var _updateActions = function() {
       
  1015         if (_canSubmit()) {
       
  1016             _removeClass(_id("action-ok"), "disabled");
       
  1017         } else {
       
  1018             _addClass(_id("action-ok"), "disabled");
       
  1019         }
       
  1020     };
       
  1021     var _canSubmit = function() {
       
  1022         var length = parseInt(_id("comment-length").innerHTML), maxLength = parseInt(_id("comment-maxlength").innerHTML), services = _state.services, service;
       
  1023         if ((maxLength > 0) && (length > maxLength)) {
       
  1024             return false;
       
  1025         }
       
  1026         for (sid in services) {
       
  1027             service = services[sid];
       
  1028             if (service.checked && service.maxTextInput && service.maxTextInput > 0) {
       
  1029                 return true;
       
  1030             }
       
  1031         }
       
  1032         return false;
       
  1033     }
       
  1034     
       
  1035     
       
  1036     var _handleSubmit = function(e) {
       
  1037         // don't accept clicks from elements with class "disabled"
       
  1038         if (/\bdisabled\b/.test(this.className)) {
       
  1039             return;
       
  1040         }
       
  1041         if (this.id == "action-ok") {
       
  1042             _addClass(this, "disabled");
       
  1043             _addClass(_id("action-cancel"), "disabled");
       
  1044             //TODO: disable testarea and service list?
       
  1045             
       
  1046             var services = _state.services, service, networks = [];
       
  1047             for (sid in services) {
       
  1048                 service = services[sid];
       
  1049                 if (service.checked) {
       
  1050                     networks.push(service.id);
       
  1051                 }
       
  1052             }
       
  1053 			
       
  1054 			var contextData = _state.contextPlayer.object.data;
       
  1055 			
       
  1056             var data = {
       
  1057                 text: _id("message").value,				
       
  1058                 object : contextData.object,
       
  1059                 networks: networks
       
  1060             };
       
  1061 			
       
  1062             ovi.player.snc.engine.publish(data, function(status, data) {
       
  1063 				if (status == ovi.player.snc.engine.status.FAILED) {
       
  1064 					alert(data.message);
       
  1065 				}
       
  1066                 _reset();
       
  1067             });
       
  1068             // TODO: call window.close here? teardown first? window.close in teardown?
       
  1069         } else {
       
  1070             ovi.player.snc.engine.cancelPublish(null, function(status, data) {
       
  1071                 _reset();
       
  1072             });
       
  1073         }
       
  1074     };
       
  1075     
       
  1076     var _reset = function() {
       
  1077         _id("shared-object").innerHTML = "";
       
  1078         _id("message").value = "";
       
  1079 		_handleMessageChange.call(_id("message"));
       
  1080         _removeClass(_id("action-cancel"), "disabled");
       
  1081 		
       
  1082 		// Request window to be closed
       
  1083 		window.close();		
       
  1084     };
       
  1085     
       
  1086 	var _sync = function(contextPlayer, handler, context) {    
       
  1087         // Sync context to UI
       
  1088         _state.contextPlayer = contextPlayer; // Store context object for publishing
       
  1089         _id("shared-object").innerHTML = _state.contextPlayer.object.data.miniview;          
       
  1090     }	
       
  1091 	
       
  1092 	
       
  1093 	var _sncInit = function(credentials, handler, context) {
       
  1094         // Sync SNC stuff
       
  1095         ovi.player.snc.engine.sync(credentials.token, function(status, data) {
       
  1096             if (status == ovi.player.snc.engine.status.FAILED) {
       
  1097                 _callback(_status.updateservices_fail, 
       
  1098 				    { message: data.message }, 
       
  1099 					handler, context);				    
       
  1100             }
       
  1101             else if (data.networks.length == 0) {
       
  1102                 _callback(_status.updateservices_nonetworks, 
       
  1103 				          { message: "No networks" }, 
       
  1104 						  handler, context);
       
  1105             }
       
  1106             else {
       
  1107                 var services = ovi.player.snc.engine.getServices();
       
  1108                 _updateServices(services, handler, context); 
       
  1109             }               
       
  1110         } );           		
       
  1111 	}
       
  1112 		   
       
  1113 
       
  1114 
       
  1115     // Register onResize for landscape / portrait mode changes
       
  1116     window.addEventListener("resize", onResize, true);
       
  1117     
       
  1118     function onResize(e) {
       
  1119         
       
  1120         function isLandscape(){
       
  1121             return window.innerWidth > window.innerHeight;
       
  1122         }   
       
  1123 		
       
  1124 		function _setMode(mode) {
       
  1125             _changeMode(_id("comment-area"), mode);
       
  1126             
       
  1127             var services = _id("available-services").children;                      
       
  1128             for(var i=0; i < services.length; i++) {
       
  1129                 _changeMode(services[i], mode);  
       
  1130             }           			
       
  1131 		}
       
  1132 		        
       
  1133         // Determine - landscape or portrait mode
       
  1134         if (isLandscape()) {		
       
  1135 			_setMode("landscape");						
       
  1136         }
       
  1137         else {
       
  1138             _setMode("portrait");			
       
  1139         }       
       
  1140     }
       
  1141 	
       
  1142 	function _changeMode(id, mode) {
       
  1143 		if (mode == "portrait") {
       
  1144             _removeClass(id, "landscape");
       
  1145 			_addClass(id, "portrait");				
       
  1146 		} else {
       
  1147             _removeClass(id, "portrait");
       
  1148 			_addClass(id, "landscape");              			
       
  1149 		}	   	
       
  1150 	}
       
  1151 	
       
  1152     /**
       
  1153      * Assign needed functions to the target namespace => defined public API.
       
  1154      */
       
  1155     targetNS.view = _show;
       
  1156     targetNS.teardown = _teardown;
       
  1157     targetNS.reset = _reset;    
       
  1158     
       
  1159     /**
       
  1160      * Synchronize context data from context object
       
  1161      */
       
  1162     targetNS.sync = _sync;
       
  1163     
       
  1164     /**
       
  1165      * Launch UI and initialize SNC
       
  1166      */
       
  1167     targetNS.create = function(options, handler, context) {
       
  1168         
       
  1169         // Show UI
       
  1170         _show(options, handler, context);
       
  1171         
       
  1172         // Start loading SNC networks
       
  1173         _sncInit(params.credentials, handler, context);
       
  1174     }			
       
  1175 	
       
  1176 	targetNS.status = _status;
       
  1177 };
       
  1178 // Create needed namespace ovi.player.share.ui
       
  1179 window["ovi"] = window["ovi"] ||
       
  1180 {};
       
  1181 ovi.player = ovi.player ||
       
  1182 {};
       
  1183 ovi.player.share = ovi.player.share ||
       
  1184 {};
       
  1185 ovi.player.share.ui = ovi.player.share.ui ||
       
  1186 {};
       
  1187 
       
  1188 /**
       
  1189  * Label UI control implementation. TODO
       
  1190  * 
       
  1191  * This API tries to imitate medos framework UI controls for future compability.
       
  1192  * @param {Object} params
       
  1193  * @param {Object} target
       
  1194  */
       
  1195 ovi.player.share.ui.Label = function(params, target) {
       
  1196     
       
  1197 	var CLICK_EVENT = "selected";
       
  1198 	var that = this;
       
  1199 
       
  1200     function createHtml() {
       
  1201 	    var template = '<span class="ovi_Label">' + params.text + '</span>';
       
  1202 	
       
  1203 	    var node = document.createElement("div");  // Do we need this ??
       
  1204 	    node.innerHTML = template;
       
  1205 		return node;		
       
  1206 	}
       
  1207 
       
  1208     var _root = createHtml();
       
  1209 	var _label = _root.firstChild;
       
  1210  
       
  1211     target.appendChild(_root);
       
  1212 	
       
  1213     this.setProperty = function(name, value) {
       
  1214 		_label[name] = value;
       
  1215 	}
       
  1216 	
       
  1217     this.getProperty = function(name) {
       
  1218         return _label[name];
       
  1219     }
       
  1220 	
       
  1221     for(var v in params) {
       
  1222         this.setProperty(v, params[v]);
       
  1223     }
       
  1224 }
       
  1225 // Create needed namespace ovi.player.share.ui
       
  1226 window["ovi"] = window["ovi"] ||
       
  1227 {};
       
  1228 ovi.player = ovi.player ||
       
  1229 {};
       
  1230 ovi.player.share = ovi.player.share ||
       
  1231 {};
       
  1232 ovi.player.share.ui = ovi.player.share.ui ||
       
  1233 {};
       
  1234 
       
  1235 /**
       
  1236  * Textarea UI control implementation. TODO
       
  1237  * 
       
  1238  * This API tries to imitate medos framework UI controls for future compability.
       
  1239  * @param {Object} params
       
  1240  * @param {Object} target
       
  1241  */
       
  1242 ovi.player.share.ui.TextArea = function(params, target) {
       
  1243     
       
  1244 	var CLICK_EVENT = "selected";
       
  1245 	var that = this;
       
  1246 
       
  1247     function createHtml() {
       
  1248 	    var template = '<textarea class="ovi_TextInput ovi_Textarea" rows="2"></textarea>';
       
  1249 	
       
  1250 	    var node = document.createElement("div");  // Do we need this ??
       
  1251 	    node.innerHTML = template;
       
  1252 		return node;		
       
  1253 	}
       
  1254 
       
  1255     var _root = createHtml();
       
  1256 	var _textarea = _root.firstChild;
       
  1257  
       
  1258     target.appendChild(_root);
       
  1259 	
       
  1260     this.setProperty = function(name, value) {
       
  1261 		_textarea[name] = value;
       
  1262 	}
       
  1263 	
       
  1264 	this.getProperty = function(name) {
       
  1265 		return _textarea[name];
       
  1266 	}
       
  1267 	
       
  1268     for(var v in params) {
       
  1269         this.setProperty(v, params[v]);
       
  1270     }	
       
  1271 }
       
  1272 window["ovi"] = window["ovi"] ||
       
  1273 {};
       
  1274 ovi.player = ovi.player ||
       
  1275 {};
       
  1276 ovi.player.snc = ovi.player.snc ||
       
  1277 {};
       
  1278 
       
  1279 ovi.player.snc.getInstance = function(config) {
       
  1280     var player = {};
       
  1281     player._cancel = function(options, handler, context) {
       
  1282         var callable = (typeof handler === "function");
       
  1283         if (callable) {
       
  1284             handler.call(context, "CANCEL_PENDING");
       
  1285         }
       
  1286         // TODO: cancel Player
       
  1287     };
       
  1288     player._pick = function(options, handler, context) {
       
  1289         var callable = (typeof handler === "function");
       
  1290         if (callable) {
       
  1291             handler.call(context, "PICK_PENDING");
       
  1292         }
       
  1293         // TODO: offer list of configured networks
       
  1294     };
       
  1295     player._view = function(options, handler, context) {
       
  1296         var callable = (typeof handler === "function");
       
  1297         if (callable) {
       
  1298             handler.call(context, "VIEW_PENDING");
       
  1299         }
       
  1300         // TODO: offer miniviews for networks list
       
  1301     };
       
  1302     player._sync = function(options, handler, context) {
       
  1303         var callable = (typeof handler === "function");
       
  1304         if (callable) {
       
  1305             handler.call(context, "SYNC_PENDING");
       
  1306         }
       
  1307         // TODO: connect to the Ovi API and SNC
       
  1308     };
       
  1309     ovi.player._getInstance.call(player, config);
       
  1310 };
       
  1311 
       
  1312 ovi.player.snc.Player = ovi.player.snc.getInstance;