/* Autogenerated with Kurento Idl */

/*
 * (C) Copyright 2013-2014 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

var inherits = require('inherits');

var checkType = require('checktype');

var ChecktypeError = checkType.ChecktypeError;

var MediaObject = require('./MediaObject');

/**
 * @classdesc
 *  Basic building blocks of the media server, that can be interconnected through the API. A {@link module:core/abstracts.MediaElement MediaElement} is a module that encapsulates a specific media capability. They can be connected to create media pipelines where those capabilities are applied, in sequence, to the stream going through the pipeline.
 *  
 *     {@link module:core/abstracts.MediaElement MediaElement} objects are classified by its supported media type (audio, video, etc.) and the flow direction: {@link module:core/abstracts.MediaSource MediaSource} pads are intended for media delivery while {@link module:core/abstracts.MediaSink MediaSinks}  behave as reception points.
 *
 * @abstract
 * @extends module:core/abstracts.MediaObject
 *
 * @constructor module:core/abstracts.MediaElement
 *
 * @param {external:String} id
 */
function MediaElement(id){
  MediaElement.super_.call(this, id);
};
inherits(MediaElement, MediaObject);


/**
 * perform {@link module:core/abstracts.MediaElement#connect(sink,mediaType)} if there is exactly one sink for the given type, and their mediaDescriptions are the same
 *
 * @alias module:core/abstracts.MediaElement.connect
 *
 * @param {module:core/abstracts.MediaElement} sink
 *  the target {@link module:core/abstracts.MediaElement MediaElement}  from which {@link module:core/abstracts.MediaSink MediaSink} will be obtained
 *
 * @param {module:core/complexTypes.MediaType} [mediaType]
 *  the {@link MediaType} of the pads that will be connected
 *
 * @param {external:String} [mediaDescription]
 *  A textual description of the media source. Currently not used, aimed mainly for {@link module:core/abstracts.MediaElement#MediaType.DATA} sources
 *
 * @param {module:core/abstracts.MediaElement~connectCallback} [callback]
 *
 * @return {external:Promise}
 */
MediaElement.prototype.connect = function(sink, mediaType, mediaDescription, callback){
  callback = arguments[arguments.length-1] instanceof Function
           ? Array.prototype.pop.call(arguments)
           : undefined;

  if(callback)
    switch(arguments.length){
      case 1: mediaType = undefined; break;
      case 2: mediaDescription = undefined; break;
    }

  checkType('MediaElement', 'sink', sink, {required: true});
  checkType('MediaType', 'mediaType', mediaType);
  checkType('String', 'mediaDescription', mediaDescription);

  var params = {
    sink: sink,
    mediaType: mediaType,
    mediaDescription: mediaDescription,
  };

  return this.invoke('connect', params, callback);
};
/**
 * @callback module:core/abstracts.MediaElement~connectCallback
 * @param {external:Error} error
 */

/**
 * A list of sinks of the given {@link module:core/complexTypes.MediaType MediaType}. The list will be empty if no sinks are found.
 *
 * @alias module:core/abstracts.MediaElement.getMediaSinks
 *
 * @param {module:core/complexTypes.MediaType} [mediaType]
 *  One of {@link module:core/abstracts.MediaElement#MediaType.AUDIO}, {@link module:core/abstracts.MediaElement#MediaType.VIDEO} or {@link module:core/abstracts.MediaElement#MediaType.DATA}
 *
 * @param {external:String} [description]
 *  A textual description of the media source. Currently not used, aimed mainly for {@link module:core/abstracts.MediaElement#MediaType.DATA} sources
 *
 * @param {module:core/abstracts.MediaElement~getMediaSinksCallback} [callback]
 *
 * @return {external:Promise}
 */
MediaElement.prototype.getMediaSinks = function(mediaType, description, callback){
  callback = arguments[arguments.length-1] instanceof Function
           ? Array.prototype.pop.call(arguments)
           : undefined;

  if(callback)
    switch(arguments.length){
      case 0: mediaType = undefined; break;
      case 1: description = undefined; break;
    }

  checkType('MediaType', 'mediaType', mediaType);
  checkType('String', 'description', description);

  var params = {
    mediaType: mediaType,
    description: description,
  };

  return this.invoke('getMediaSinks', params, callback);
};
/**
 * @callback module:core/abstracts.MediaElement~getMediaSinksCallback
 * @param {external:Error} error
 * @param {module:core/abstracts.MediaSink} result
 *  A list of sinks. The list will be empty if no sinks are found.
 */

/**
 * Get the media sources of the given type and description
 *
 * @alias module:core/abstracts.MediaElement.getMediaSrcs
 *
 * @param {module:core/complexTypes.MediaType} [mediaType]
 *  One of {@link module:core/abstracts.MediaElement#MediaType.AUDIO}, {@link module:core/abstracts.MediaElement#MediaType.VIDEO} or {@link module:core/abstracts.MediaElement#MediaType.DATA}
 *
 * @param {external:String} [description]
 *  A textual description of the media source. Currently not used, aimed mainly for {@link module:core/abstracts.MediaElement#MediaType.DATA} sources
 *
 * @param {module:core/abstracts.MediaElement~getMediaSrcsCallback} [callback]
 *
 * @return {external:Promise}
 */
MediaElement.prototype.getMediaSrcs = function(mediaType, description, callback){
  callback = arguments[arguments.length-1] instanceof Function
           ? Array.prototype.pop.call(arguments)
           : undefined;

  if(callback)
    switch(arguments.length){
      case 0: mediaType = undefined; break;
      case 1: description = undefined; break;
    }

  checkType('MediaType', 'mediaType', mediaType);
  checkType('String', 'description', description);

  var params = {
    mediaType: mediaType,
    description: description,
  };

  return this.invoke('getMediaSrcs', params, callback);
};
/**
 * @callback module:core/abstracts.MediaElement~getMediaSrcsCallback
 * @param {external:Error} error
 * @param {module:core/abstracts.MediaSource} result
 *  A list of sources. The list will be empty if no sources are found.
 */

/**
 * Sets the type of data for the audio stream. MediaElements that do not support configuration of audio capabilities will raise an exception
 *
 * @alias module:core/abstracts.MediaElement.setAudioFormat
 *
 * @param {module:core/complexTypes.AudioCaps} caps
 *  The format for the stream of audio
 *
 * @param {module:core/abstracts.MediaElement~setAudioFormatCallback} [callback]
 *
 * @return {external:Promise}
 */
MediaElement.prototype.setAudioFormat = function(caps, callback){
  checkType('AudioCaps', 'caps', caps, {required: true});

  var params = {
    caps: caps,
  };

  return this.invoke('setAudioFormat', params, callback);
};
/**
 * @callback module:core/abstracts.MediaElement~setAudioFormatCallback
 * @param {external:Error} error
 */

/**
 * Sets the type of data for the video stream. MediaElements that do not support configuration of video capabilities will raise an exception
 *
 * @alias module:core/abstracts.MediaElement.setVideoFormat
 *
 * @param {module:core/complexTypes.VideoCaps} caps
 *  The format for the stream of video
 *
 * @param {module:core/abstracts.MediaElement~setVideoFormatCallback} [callback]
 *
 * @return {external:Promise}
 */
MediaElement.prototype.setVideoFormat = function(caps, callback){
  checkType('VideoCaps', 'caps', caps, {required: true});

  var params = {
    caps: caps,
  };

  return this.invoke('setVideoFormat', params, callback);
};
/**
 * @callback module:core/abstracts.MediaElement~setVideoFormatCallback
 * @param {external:Error} error
 */

/**
 * @alias module:core/abstracts.MediaElement.constructorParams
 */
MediaElement.constructorParams = {};

/**
 * @alias module:core/abstracts.MediaElement.events
 *
 * @extend module:core/abstracts.MediaObject.events
 */
MediaElement.events = MediaObject.events;

module.exports = MediaElement;

MediaElement.check = function(key, value)
{
  if(!(value instanceof MediaElement))
    throw ChecktypeError(key, MediaElement, value);
};
