////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.controls.videoClasses 
{

import flash.events.Event;
import flash.events.NetStatusEvent;
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.utils.Timer;
import mx.managers.ISystemManager;
import mx.managers.SystemManager;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;

[ExcludeClass]

[ResourceBundle("controls")]

/**
 *  @private
 *  Creates <code>NetConnection</code> for <code>VideoPlayer</code>, a
 *  helper class for that user facing class.
 */
public class NCManager implements INCManager
{
    include "../../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     *  Default connection timeout in milliseconds.
     *
     *  @see #timeout
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static const DEFAULT_TIMEOUT:Number = 60000;

    /**
     *  @private
     */
    private static const DEFAULT_NC_TIMEOUT:uint = 1500;       // .5 seconds

    //--------------------------------------------------------------------------
    //
    //  Class variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  List of connections tried by connectRTMP, in order tried.
     */
    private static var RTMP_CONN:Array =
    [
        { protocol: "rtmp:/", port: "1935" },
        { protocol: "rtmp:/", port:"443" },
        { protocol: "rtmpt:/", port:"80" },
        { protocol: "rtmps:/", port:"443" }
    ];
                
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
  
    /**
     *  @private
     *  Constructor.
     */    
    public function NCManager()    
    {
        super();

        initNCInfo();
        initOtherInfo();

        // intervals
        owner = null;
        _netConnection = null;
        ncConnected = false;

        // actually calls setter
        timeout = DEFAULT_TIMEOUT;
    }
     
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     * <p>fallbackServerName is exposed in two ways:</p>
     * 
     * <p>User can supply second <meta base> in smil and that base
     * attr will be taken as the fallbackServerName (note that only
     * the server name will be taken from this and not the application
     * name or anything else).</p>
     *
     * <p>The second way is the user can directly set this by
     * accessing the ncMgr property in FLVPlayback or VideoPlayer and
     * set fallbackServerName property directly.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public var fallbackServerName:String;
    
    /**
     *  @private
     *  Reference to the VideoPlayer instance associated with this INCManager.
     */
    private var owner:VideoPlayer;

    /**
     *  @private
     *  The path to the content.
     */
    private var contentPath:String;
    
    /**
     *  @private
     */    
    private var protocol:String;
    
    /**
     *  @private
     *  The host name portion of the URL.
     */
    private var serverName:String;

    /**
     *  @private
     *  The port number portion of the URL.
     */
    private var portNumber:String;
    
    /**
     *  @private
     */    
    private var wrappedURL:String;
    
    /**
     *  @private
     */
    private var appName:String;

    /**
     *  @private
     *  Multiple streams for multiple bandwidths.
     */
    private var streams:Array;

    /**
     *  @private
     *  Whether the protocol is RTMP.
     *   -1: undefined
     *    0: no
     *    1: yes
     */
    private var _isRTMP:int = -1;

    /**
     *  @private
     *  Timer for connection timeout.
     */
    private var connectionTimer:Timer;

    /**
     *  @private
     */
    private var autoSenseBW:Boolean;

    /**
     *  @private
     *  Bandwidth detection stuff.
     */
    public var payload:uint;

    /**
     *  @private
     *  Value of the NetConnection instance's uri property.  This is saved upon
     *  connection and reused for reconnecting.
     */
    private var ncURI:String;

    /**
     *  @private
     */
    private var ncConnected:Boolean;
    
    /**
     *  @private
     *  Info on multiple connections we try.
     */
    public var tryNC:Array;

    /**
     *  @private
     */
    private var tryNCTimer:Timer;


    /**
     *  @private
     *  Counter that tracks the next type to try in RTMP_CONN.
     */
    private var connTypeCounter:uint;

    /**
     *  @private
     *  Used for accessing localized Error messages.
     */
    private var resourceManager:IResourceManager =
                                    ResourceManager.getInstance();

    //--------------------------------------------------------------------------
    //
    //  Public Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  timeout
    //----------------------------------

    /**
     *  @private
     *  Storage for timeout property.
     */
    private var _timeout:uint;

    /**
     *  @see INCManager#timeout
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get timeout():uint 
    {
        return _timeout;
    }

    public function set timeout(t:uint):void 
    {
        _timeout = t;
        connectionTimer = new Timer(_timeout, 1);
        connectionTimer.addEventListener(TimerEvent.TIMER, onFCSConnectTimeOut);
    }

    //----------------------------------
    //  bitrate
    //----------------------------------

    /**
     *  @private
     *  Storage for bitrate property.
     */
    private var _bitrate:Number;

    /**
     *  For RTMP streams, returns value calculated from autodetection,
     *  not value set via bitrate.
     *
     *  @see INCManager#bitrate
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get bitrate():Number 
    {
        return _bitrate;
    }

    /**
     *  This value is only used with progressive download (HTTP), with
     *  RTMP streaming uses autodetection.
     *
     *  @see INCManager#bitrate
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function set bitrate(b:Number):void 
    {
        if (_isRTMP == 0)
            _bitrate = b;
    }

    //----------------------------------
    //  videoPlayer
    //----------------------------------

    /**
     *  @see INCManager#videoPlayer
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get videoPlayer():VideoPlayer 
    {
        return owner;
    }

    /**
     *  @private
     */
    public function set videoPlayer(value:VideoPlayer):void 
    {
        owner = value;
    }

    //----------------------------------
    //  netConnection
    //----------------------------------

    /**
     *  @private
     */
    private var _netConnection:NetConnection;

    /**
     *  @see INCManagernetConnection
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get netConnection():NetConnection 
    {
        return _netConnection;
    }

    //----------------------------------
    //  streamName
    //----------------------------------

    /**
     *  @private
     *  Storage for streamName property.
     */
    private var _streamName:String;

    /**
     *  @see INCManager#streamName
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get streamName():String 
    {
        return _streamName;
    }

    //----------------------------------
    //  streamLength
    //----------------------------------

    /**
     *  @private
     *  Storage for streamLength property.
     */
    private var _streamLength:Number;

    /**
     *  @see INCManager#streamLength
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get streamLength():Number 
    {
        return _streamLength;
    }

    //----------------------------------
    //  streamWidth
    //----------------------------------

    /**
     *  @private
     *  Storage for streamWidth property.
     */
    private var _streamWidth:Number;

    /**
     *  @see INCManager#streamWidth
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get streamWidth():Number 
    {
        return _streamWidth;
    }

    //----------------------------------
    //  streamHeight
    //----------------------------------

    /**
     *  @private
     *  Storage for streamHeight property.
     */
    private var _streamHeight:Number;

    /**
     *  @see INCManager#streamHeight
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get streamHeight():Number 
    {
        return _streamHeight;
    }

    //--------------------------------------------------------------------------
    //
    //  Public methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @see INCManager#isRTMP
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function isRTMP():Boolean
    {
        return _isRTMP != 0;
    }

    /**
     *  @see INCManager#connectToURL()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function connectToURL(url:String):Boolean
    {
        initOtherInfo();
        
        contentPath = url;
        if (!contentPath || contentPath == "")
            throw new VideoError(VideoError.INVALID_CONTENT_PATH);

        // parse URL to determine what to do with it
        var parseResults:Object = parseURL(contentPath);

        if (!parseResults.streamName || parseResults.streamName == "")
            throw new VideoError(VideoError.INVALID_CONTENT_PATH, url);

        // connect to either rtmp or http or download and parse smil
        if (parseResults.isRTMP)
        {
            var canReuseRTMP:Boolean = canReuseOldConnection(parseResults);
            _isRTMP = 1;
            protocol = parseResults.protocol;
            _streamName = parseResults.streamName;
            serverName = parseResults.serverName;
            wrappedURL = parseResults.wrappedURL;
            portNumber = parseResults.portNumber;
            appName = parseResults.appName;
            if ( !appName || appName == "" ||
                 !_streamName || _streamName == "" )
                throw new VideoError(VideoError.INVALID_CONTENT_PATH, url);
            autoSenseBW = (_streamName.indexOf(",") >= 0);
            return (canReuseRTMP || connectRTMP());         
        }
        else
        {
            var canReuseHTTP:Boolean = canReuseOldConnection(parseResults);                
            _isRTMP = 0;
            _streamName = parseResults.streamName;
            return (canReuseHTTP || connectHTTP());
        }
    }

    /**
     *  @see INCManager#connectAgain()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function connectAgain():Boolean
    {
        var slashIndex:Number = appName.indexOf("/");
        if (slashIndex < 0) 
        {
            // return the appName and streamName back to original form
            // so we can start this process all over again with the
            // fallback server if necessary
            slashIndex = _streamName.indexOf("/");
            if (slashIndex >= 0) 
            {
                appName += "/";
                appName += _streamName.slice(0, slashIndex);
                _streamName = _streamName.slice(slashIndex + 1);
            }
            return false;
        }

        var newStreamName:String = appName.slice(slashIndex + 1);
        newStreamName += "/";
        newStreamName += _streamName;
        _streamName = newStreamName;
        appName = appName.slice(0, slashIndex);
        close();
        payload = 0;
        connTypeCounter = 0;
        cleanConns();
        connectRTMP();
        return true;
    }
    
    /**
     * INCManager#reconnect
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function reconnect():void
    {
        if (!_isRTMP)
        {
            var message:String = resourceManager.getString(
                "controls", "invalidCall");
            throw new Error(message);
        }

        _netConnection.addEventListener(NetStatusEvent.NET_STATUS, reconnectOnStatus);
        _netConnection.client = new NCManagerReconnectClient(this);
        _netConnection.connect(ncURI, false);
    }

    /**
     *  @see INCManager#close
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function close():void
    {
        if (_netConnection)
        {
            _netConnection.close();
            ncConnected = false;
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Private Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Initialization.
     */
    private function initNCInfo():void
    {
        _isRTMP = -1;
        serverName = null;
        wrappedURL = null;
        portNumber = null;
        appName = null;
    }

    private function initOtherInfo():void 
    {
        contentPath = null;        
        _streamName = null;
        _streamLength = -1;
        _streamWidth = -1;
        _streamHeight = -1;
        streams = null;
        autoSenseBW = false;

        payload = 0;
        connTypeCounter = 0;
        cleanConns();
    }

    /**
     *  matches bitrate with stream
     *
     *  @private
     */
    private function bitrateMatch():void
    {
        var whichStream:Number;
        var checkBitrate:Number = _bitrate;

        if (isNaN(checkBitrate))
            checkBitrate = 0;
        
        for (var j:uint = 0; j < streams.length; j++)
            if (isNaN(streams[j].bitrate) || checkBitrate >= streams[j].bitrate)
            {
                whichStream = j;
                break;
            }

        if (isNaN(whichStream))
            throw new VideoError(VideoError.NO_BITRATE_MATCH);

        if (_streamName)
            _streamName += streams[whichStream].src;
        else
            _streamName = streams[whichStream].src;

        _streamLength = streams[whichStream].dur;
    }

    /**
     *  <p>Parses URL to determine if it is http or rtmp.  If it is rtmp,
     *  breaks it into pieces to extract server URL and port, application
     *  name and stream name.  If .flv is at the end of an rtmp URL, it
     *  will be stripped off.</p>
     *
     *  @private
     */
    private function parseURL(url:String):Object
    {
        var parseResults:Object = {};
        
        // get protocol
        var startIndex:uint = 0;
        var endIndex:int = url.indexOf(":/", startIndex);
        if (endIndex >= 0) 
        {
            endIndex += 2;
            parseResults.protocol = url.slice(startIndex, endIndex);
            parseResults.isRelative = false;
        } 
        else
            parseResults.isRelative = true;
        
        if ( parseResults.protocol != null &&
                 ( parseResults.protocol == "rtmp:/" ||
                   parseResults.protocol == "rtmpt:/" ||
                   parseResults.protocol == "rtmps:/" ||
                   parseResults.protocol == "rtmpe:/" ||
                   parseResults.protocol == "rmpte:/" ) )
        {
            parseResults.isRTMP = true;
            
            startIndex = endIndex;

            if (url.charAt(startIndex) == '/') 
            {
                startIndex++;
                // get server (and maybe port)
                var colonIndex:Number = url.indexOf(":", startIndex);
                var slashIndex:Number = url.indexOf("/", startIndex);
                if (slashIndex < 0) 
                {
                    if (colonIndex < 0)
                        parseResults.serverName = url.slice(startIndex);
                    else 
                    {
                        endIndex = colonIndex;
                        parseResults.portNumber = url.slice(startIndex, endIndex);
                        startIndex = endIndex + 1;
                        parseResults.serverName = url.slice(startIndex);
                    }
                    return parseResults;
                }
                if (colonIndex >= 0 && colonIndex < slashIndex) 
                {
                    endIndex = colonIndex;
                    parseResults.serverName = url.slice(startIndex, endIndex);
                    startIndex = endIndex + 1;
                    endIndex = slashIndex;
                    parseResults.portNumber = url.slice(startIndex, endIndex);
                } 
                else 
                {
                    endIndex = slashIndex;
                    parseResults.serverName = url.slice(startIndex, endIndex);
                }
                startIndex = endIndex + 1;
            }

            // handle wrapped RTMP servers bit recursively, if it is there
            if (url.charAt(startIndex) == '?') 
            {
                var subURL:String = url.slice(startIndex + 1);
                var subParseResults:Object = parseURL(subURL);
                if (!subParseResults.protocol || !subParseResults.isRTMP)
                    throw new VideoError(VideoError.INVALID_CONTENT_PATH, url);
                parseResults.wrappedURL = "?";
                parseResults.wrappedURL += subParseResults.protocol;
                if (subParseResults.serverName != null) 
                {
                    parseResults.wrappedURL += "/";
                    parseResults.wrappedURL +=  subParseResults.server;
                }
                if (subParseResults.wrappedURL != null) 
                {
                    parseResults.wrappedURL += "/?";
                    parseResults.wrappedURL +=  subParseResults.wrappedURL;
                }
                parseResults.appName = subParseResults.appName;
                parseResults.streamName = subParseResults.streamName;
                return parseResults;
            }
            
            // get application name
            endIndex = url.indexOf("/", startIndex);
            if (endIndex < 0) 
            {
                parseResults.appName = url.slice(startIndex);
                return parseResults;
            }
            parseResults.appName = url.slice(startIndex, endIndex);
            startIndex = endIndex + 1;

            // check for instance name to be added to application name
            endIndex = url.indexOf("/", startIndex);
            if (endIndex < 0) 
            {
                parseResults.streamName = url.slice(startIndex);
                // strip off .flv and .flv2 if included
                if (parseResults.streamName.slice(-5).toLowerCase() == ".flv2")
                    parseResults.streamName = parseResults.streamName.slice(0, -5);
                else if (parseResults.streamName.slice(-4).toLowerCase() == ".flv")
                    parseResults.streamName = parseResults.streamName.slice(0, -4);
                return parseResults;
            }
            parseResults.appName += "/";
            parseResults.appName += url.slice(startIndex, endIndex);
            startIndex = endIndex + 1;
                
            // get flv name
            parseResults.streamName = url.slice(startIndex);
            // strip off .flv and .flv2 if included
            if (parseResults.streamName.slice(-5).toLowerCase() == ".flv2")
                parseResults.streamName = parseResults.streamName.slice(0, -5);
            else if (parseResults.streamName.slice(-4).toLowerCase() == ".flv")
                parseResults.streamName = parseResults.streamName.slice(0, -4);
            
        } 
        else 
        {
            // is http, just return the full url received as streamName
            parseResults.isRTMP = false;
            parseResults.streamName = url;
        }

        return parseResults;
    }

    /**
     *  @private
     *  <p>Handles creating <code>NetConnection</code> instance for
     *  progressive download of FLV via http.</p>
     */
    private function connectHTTP():Boolean
    {
        _netConnection = new NetConnection();
        _netConnection.objectEncoding = ObjectEncoding.AMF0;
        _netConnection.connect(null);
        ncConnected = true;
        return true;
    }

    /**
     *  @private
     *  <p>Top level function for creating <code>NetConnection</code>
     *  instance for streaming playback of FLV via rtmp.  Actually
     *  tries to create several different connections using different
     *  protocols and ports in a pipeline, so multiple connection
     *  attempts may be occurring simultaneously, and will use the
     *  first one that connects successfully.</p>
     */
    private function connectRTMP():Boolean
    {
        // setup timeout
        connectionTimer.reset();
        connectionTimer.start();

        tryNC = [];

        tryNCTimer = new Timer(DEFAULT_NC_TIMEOUT);
        tryNCTimer.addEventListener(TimerEvent.TIMER, nextConnect);

        for (var i:uint = 0; i < RTMP_CONN.length; i++)
        {
            tryNC[i] = new NetConnection();
            tryNC[i].objectEncoding = ObjectEncoding.AMF0;
            tryNC[i].client = new NCManagerConnectClient(tryNC[i], this, i);
            tryNC[i].addEventListener(NetStatusEvent.NET_STATUS, connectOnStatus);
        }

        nextConnect(null);
        return false;
    }

    /**
     *  @private
     *  <p>Does work of trying to open rtmp connections.  Called either
     *  by <code>connectRTMP</code> or <code>Timer</code> set up in
     *  that method.</p>
     *
     *  <p>For creating rtmp connections.</p>
     * 
     *  @see #connectRTMP()
     */
    private function nextConnect(event:Event):void
    {
        tryNCTimer.reset();

        var tempProtocol:String;
        var port:String;
        if (connTypeCounter == 0) 
        {
            tempProtocol = protocol;
            if (portNumber)
                port = portNumber;
            else 
                for (var i:Number = 0; i < RTMP_CONN.length; i++)
                    if (protocol == RTMP_CONN[i].protocol) 
                    {
                        port = RTMP_CONN[i].port;
                        break;
                    }
        } 
        else 
        {
            tempProtocol = RTMP_CONN[connTypeCounter].protocol;
            port = RTMP_CONN[connTypeCounter].port;
        }
        var connectionURL:String = tempProtocol + ((!serverName) ? "" : 
            "/" + serverName + ":" + port + "/") + ((!wrappedURL) ? "" : 
            wrappedURL + "/") + appName;

        tryNC[connTypeCounter].client.pending = true;
        tryNC[connTypeCounter].connect(connectionURL, autoSenseBW);

        if (connTypeCounter < RTMP_CONN.length - 1)
        {
            connTypeCounter++;
            tryNCTimer.start();
        }
    }

    /**
     *  @private
     *  <p>Stops all timers, closes all unneeded connections, and other
     *  cleanup related to the <code>connectRTMP</code> strategy of
     *  pipelining connection attempts to different protocols and
     *  ports.</p>
     *
     *  <p>For creating rtmp connections.</p>
     *
     *  @see #connectRTMP()
     */
    private function cleanConns():void
    {
        if (tryNCTimer != null)
        {
            tryNCTimer.reset();
            tryNCTimer = null;
        }

        if (tryNC)
        {
            for (var i:uint = 0; i < tryNC.length; i++)
            {
                if (tryNC[i])
                {
                    tryNC[i].removeEventListener(NetStatusEvent.NET_STATUS, connectOnStatus);
                    if (tryNC[i].client.pending)
                        tryNC[i].addEventListener(NetStatusEvent.NET_STATUS, disconnectOnStatus);
                    else
                        tryNC[i].close();
                }
                tryNC[i] = null;
            }
            tryNC = null;
        }
    }

    /**
     *  @private
     *  <p>Starts another pipelined connection attempt with
     *  <code>connectRTMP</code> with the fallback server.</p>
     *
     *  <p>For creating rtmp connections.</p>
     *
     *  @see #connectRTMP()
     */
    private function tryFallBack():void
    {
        if (serverName == fallbackServerName || !fallbackServerName)
        {
            //it's not connected
            _netConnection = null;
            ncConnected = false;
            owner.ncConnected();
        }
        else
        {
            connTypeCounter = 0;
            cleanConns();
            serverName = fallbackServerName;
            connectRTMP();
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Callbacks and event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  dispatches reconnect event, called by
     *  <code>NetConnection.onBWDone</code>
     */
    public function onReconnected():void
    {
        _netConnection.removeEventListener(NetStatusEvent.NET_STATUS, connectOnStatus);
        ncConnected = true;
        owner.ncReconnected();
    }

    /**
     *  @private
     *  <p>Starts another pipelined connection attempt with
     *  <code>connectRTMP</code> with the fallback server.</p>
     *
     *  <p>For creating rtmp connections.</p>
     *
     *  @see #connectRTMP()
     */
    public function onConnected(p_nc:NetConnection, p_bw:Number):void
    {
        // avoid timeout
        connectionTimer.reset();

        // ditch these now unneeded functions and listeners
        // Don't need to assign the client to null
        // since it will anyways get reassigned on
        // reconnection.
        // p_nc.client = null;
        p_nc.removeEventListener(NetStatusEvent.NET_STATUS, connectOnStatus);
        
        // store pointers to the successful connection and uri
        _netConnection = p_nc;
        ncURI = _netConnection.uri;
        ncConnected = true;

        if (autoSenseBW)
        {
            _bitrate = p_bw * 1024;

            if (streams)
                bitrateMatch();
            else
            {
                var sSplit:Array = _streamName.split(",");

                // remove leading and trailing whitespace from string
                for (var i:uint = 0; i < sSplit.length; i+=2)
                {
                    var sName:String = sSplit[i].replace(/^\s*(\S.*\S)\s*$/, "$1");
                    if (i + 1 < sSplit.length)
                    {
                        // If we have less bw than the next threshold or if
                        // there isn't another threshold (last string)
                        if (p_bw <= Number(sSplit[i+1]))
                        {
                            _streamName = sName;
                            break;
                        }
                    }
                    else
                    {
                        _streamName = sName;
                        break;
                    }
                } // for
                // strip off .flv and .flv2 if included
                if (_streamName.slice(-5).toLowerCase() == ".flv2")
                    _streamName = _streamName.slice(0, -5);   
                else if (_streamName.slice(-4).toLowerCase() == ".flv")
                    _streamName = _streamName.slice(0, -4);                
            }
        }


        // if we need to get the stream length from the server, do it here
        // Donot call getStreamLength when main.asc is not present
        // since getStreamLength is defined in main.asc
        if ((!owner.isLive && _streamLength == -1) && owner.autoBandWidthDetection)
        {
            var res:Responder = new Responder(getStreamLengthResult,
                    getStreamLengthStatus);
            _netConnection.call("getStreamLength", res, _streamName);
        }
        else
            owner.ncConnected();
    }

    /**
     *  @private
     *  netStatus event listener when connecting
     */
    public function connectOnStatus(event:NetStatusEvent):void
    {
        var stuff:Object;
        var target:NetConnection = NetConnection(event.target);

        target.client.pending = false;

        if (event.info.code == "NetConnection.Connect.Success")
        {
            _netConnection = tryNC[target.client.connIndex];
            // Force call to onConnected when main.asc is not present
            // which would call this function through onBWDone
            if (!owner.autoBandWidthDetection)
                onConnected(_netConnection, 0);
            tryNC[target.client.connIndex] = null;
            cleanConns();
        }
        else if (((event.info.code == "NetConnection.Connect.Failed")
                    || (event.info.code == "NetConnection.Connect.Rejected"))
                    && (target.client.connIndex == (RTMP_CONN.length - 1)))
            // Try rearranging the app URL, then the fallbackServer
            if (!connectAgain())
                tryFallBack();
    }

    /**
     *  @private
     *  netStatus event listener when reconnecting
     */
    public function reconnectOnStatus(event:NetStatusEvent):void
    {
        if ((event.info.code == "NetConnection.Connect.Failed")
                || (event.info.code == "NetConnection.Connect.Rejected"))
        {
            // Try the fallbackServer
            _netConnection = null;
            ncConnected = false;
            owner.ncReconnected();
        }
    }

    /**
     *  @private
     *  netStatus event listener for disconnecting extra
     *  NetConnections that were opened in parallel
     */
    public function disconnectOnStatus(event:NetStatusEvent):void
    {
        if (event.info.code == "NetConnection.Connect.Success")
        {
            event.target.removeEventListener(NetStatusEvent.NET_STATUS,
                    disconnectOnStatus);
            NetConnection(event.target).close();
        }
    }

    /**
     *  @private
     *  Responder function to receive streamLength result from
     *  server after making rpc
     */
    private function getStreamLengthResult(length:Number):void
    {
        if (length > 0)
            _streamLength = length;
        owner.ncConnected();
    }

    /**
     *  @private
     *  Responder function to receive status messages for rpc to
     *  get streamLength
     */
    private function getStreamLengthStatus(item:Object):void 
    {
    }

    /**
     *  @private
     *  <p>Called by timer to timeout all connection attempts.</p>
     *
     *  <p>For creating rtmp connections.</p>
     *
     *  @see #connectRTMP()
     */
    private function onFCSConnectTimeOut(event:Event):void
    {
        cleanConns();
        _netConnection = null;
        ncConnected = false;
        if (!connectAgain())
            owner.ncConnected();
    }
    
    /**
     *  @private     
     *  <p>Compares connection info with previous NetConnection,
     *  will reuse existing connection if possible.
     */
    private function canReuseOldConnection(parseResults:Object):Boolean 
    {
        // no reuse if no prior connection
        if (_netConnection == null || !ncConnected) 
            return false;

        // http connection
        if (!parseResults.isRTMP) 
        {
            // can reuse if prev connection was http
            if (!_isRTMP) 
                return true;
            // cannot reuse if was rtmp--close
            owner.close();
            _netConnection = null;
            ncConnected = false;
            initNCInfo();
            return false;
        }

        // rtmp connection
        if (_isRTMP) 
        {
            if (parseResults.serverName == serverName && parseResults.appName == appName &&
                 parseResults.protocol == protocol && parseResults.portNumber == portNumber &&
                 parseResults.wrappedURL == wrappedURL)
                return true;
            // cannot reuse this rtmp--close
            owner.close();
            _netConnection = null;
            ncConnected = false;
        }

        initNCInfo();
        return false;
    }

} // class mx.controls.videoClasses.NCManager
}
