/**
* the SrsPublisher object.
* @param container the html container id.
* @param width a float value specifies the width of publisher.
* @param height a float value specifies the height of publisher.
* @param private_object [optional] an object that used as private object, 
*       for example, the logic chat object which owner this publisher.
*/
function SrsPublisher(container, width, height, private_object) {
    if (!SrsPublisher.__id) {
        SrsPublisher.__id = 100;
    }
    if (!SrsPublisher.__publishers) {
        SrsPublisher.__publishers = [];
    }
    
    SrsPublisher.__publishers.push(this);
    
    this.private_object = private_object;
    this.container = container;
    this.width = width;
    this.height = height;
    this.id = SrsPublisher.__id++;
    this.callbackObj = null;
    
    // set the values when publish.
    this.url = null;
    this.vcodec = {};
    this.acodec = {};
    
    // callback set the following values.
    this.cameras = [];
    this.microphones = [];
    this.code = 0;
    
    // error code defines.
    this.errors = {
        "100": "无法获取指定的摄像头。", //error_camera_get 
        "101": "无法获取指定的麦克风。", //error_microphone_get 
        "102": "摄像头为禁用状态，推流时请允许flash访问摄像头。", //error_camera_muted 
        "103": "服务器关闭了连接。", //error_connection_closed 
        "104": "服务器连接失败。", //error_connection_failed 
        "199": "未知错误。"
    };
}
/**
* user can set some callback, then start the publisher.
* callbacks:
*      on_publisher_ready(cameras, microphones):int, when srs publisher ready, user can publish.
*      on_publisher_error(code, desc):int, when srs publisher error, callback this method.
*      on_publisher_warn(code, desc):int, when srs publisher warn, callback this method.
*/
SrsPublisher.prototype.start = function() {
    // embed the flash.
    var flashvars = {};
    flashvars.id = this.id;
    flashvars.width = this.width;
    flashvars.height = this.height;
    flashvars.on_publisher_ready = "__srs_on_publisher_ready";
    flashvars.on_publisher_error = "__srs_on_publisher_error";
    flashvars.on_publisher_warn = "__srs_on_publisher_warn";
    
    var params = {};
    params.wmode = "opaque";
    params.allowFullScreen = "true";
    params.allowScriptAccess = "always";
    
    var attributes = {};
    
    var self = this;
    
    swfobject.embedSWF(
        "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(), 
        this.container,
        this.width, this.height,
        "11.1.0", "js/AdobeFlashPlayerInstall.swf",
        flashvars, params, attributes,
        function(callbackObj){
            self.callbackObj = callbackObj;
        }
    );
    
    return this;
}
/**
* publish stream to server.
* @param url a string indicates the rtmp url to publish.
* @param vcodec an object contains the video codec info.
* @param acodec an object contains the audio codec info.
*/
SrsPublisher.prototype.publish = function(url, vcodec, acodec) {
    this.stop();
    SrsPublisher.__publishers.push(this);
    
    if (url) {
        this.url = url;
    }
    if (vcodec) {
        this.vcodec = vcodec;
    }
    if (acodec) {
        this.acodec = acodec;
    }
    
    this.callbackObj.ref.__publish(this.url, this.width, this.height, this.vcodec, this.acodec);
}
SrsPublisher.prototype.stop = function() {
    for (var i = 0; i < SrsPublisher.__publishers.length; i++) {
        var player = SrsPublisher.__publishers[i];
        
        if (player.id != this.id) {
            continue;
        }
        
        SrsPublisher.__publishers.splice(i, 1);
        break;
    }
    
    this.callbackObj.ref.__stop();
}
/**
* when publisher ready.
* @param cameras a string array contains the names of cameras.
* @param microphones a string array contains the names of microphones.
*/
SrsPublisher.prototype.on_publisher_ready = function(cameras, microphones) {
}
/**
* when publisher error.
* @code the error code.
* @desc the error desc message.
*/
SrsPublisher.prototype.on_publisher_error = function(code, desc) {
    throw new Error("publisher error. code=" + code + ", desc=" + desc);
}
SrsPublisher.prototype.on_publisher_warn = function(code, desc) {
    throw new Error("publisher warn. code=" + code + ", desc=" + desc);
}
function __srs_find_publisher(id) {
    for (var i = 0; i < SrsPublisher.__publishers.length; i++) {
        var publisher = SrsPublisher.__publishers[i];
        
        if (publisher.id != id) {
            continue;
        }
        
        return publisher;
    }
    
    throw new Error("publisher not found. id=" + id);
}
function __srs_on_publisher_ready(id, cameras, microphones) {
    var publisher = __srs_find_publisher(id);
    
    publisher.cameras = cameras;
    publisher.microphones = microphones;
    
    publisher.on_publisher_ready(cameras, microphones);
}
function __srs_on_publisher_error(id, code) {
    var publisher = __srs_find_publisher(id);
    
    publisher.code = code;
    
    publisher.on_publisher_error(code, publisher.errors[""+code]);
}
function __srs_on_publisher_warn(id, code) {
    var publisher = __srs_find_publisher(id);
    
    publisher.code = code;
    
    publisher.on_publisher_warn(code, publisher.errors[""+code]);
}
