/****************************************************************
* Master.as, by Christopher Olsen <cwolsen@domainatlantic.com>
* Copyright 2007 Christopher Olsen
* Mark Iuzzolino
*
* This is the Master class used by the TUve player
*
* $Id$
***************************************************************/
package {
import flash.net.NetConnection;
import flash.net.NetStream;
import mx.collections.ArrayCollection;
import flash.net.Responder;
import mx.managers.PopUpManager;
import mx.controls.Alert;
import mx.controls.Image;
import flash.utils.Timer;
import flash.events.TimerEvent;
import mx.events.FlexEvent;
import flash.media.*;
import mx.core.UIComponent;
import flash.net.ObjectEncoding;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import tuveNetwork;
import flash.events.AsyncErrorEvent;
import flash.net.SharedObject;
import mx.formatters.NumberFormatter;
import flash.system.System;
import mx.controls.TextArea;
import mx.managers.PopUpManager;
import mx.core.Application;
import flash.filters.DropShadowFilter;
public class Master {
/* Variables */
public var gateway:NetConnection; // AMF Gateway
public var masterObject:Object; // Parent reference
[Bindable]
public var userName:String; // User Infomation
public var tvNetwork:tuveNetwork;
/* Video Area */
public var tvVidHolder:UIComponent = new UIComponent();
public var tvVid:Video;
private var tvOverlay:Image;
private var ds:DropShadowFilter;
public var tvNC:NetConnection;
public var tvNS:NetStream;
public var tvST:SoundTransform;
public var tvStartTime:Number;
public var tvGotMeta:Boolean = false;
public var curSong:String = "NO SONG SET";
public var myTimer:Timer = new Timer(1000,10);
public var myCount:Number = 0;
[Bindable]
public var userList:XMLList;
[Bindable]
public var songList:ArrayCollection;
[Bindable]
public var topicHistory:XMLList;
[Bindable]
public var myQueue:ArrayCollection;
public var tvCurRating:Number;
[Bindable]
public var tvRating:XMLList =
<>
<mi label="G" data="1" />
<mi label="PG" data="2" />
<mi label="13+" data="3" />
<mi label="MA" data="4" />
<mi label="AD" data="5" />
</>;
[Bindable]
public var chanList:XMLList =
<>
<mi label="General" data="#general" />
<mi label="Documentaries" data="#documentaries" />
<mi label="EuroPop" data="#europop" />
<mi label="Top 40" data="#top40" />
<mi label="TCA's Picks" data="#tca" />
<mi label="Da Dog House" data="#doghouse" />
</>;
public var tvCurClass:Number;
[Bindable]
public var tvClass:XMLList =
<>
<mi label="All" data="0" />
<mi label="Anime/Toons" data="3" />
<mi label="Documentary" data="5" />
<mi label="Movie" data="4" />
<mi label="Music Video" data="1" />
<mi label="TV" data="2" />
<mi label="Original" data="6" />
</>;
public var currentChannel:String;
[Bindable]
public var channels:XMLList;
[Bindable]
private var metaData:Object = {duration:0};
private var imWins:Array;
public var tvSO:SharedObject;
public var vid:Number;
/* Pop Up Windows */
private var tuveLW:listWindow;
public var tuveSW:searchWindow;
public var tuveIW:infoWindow;
public var tuveFW:formatWindow;
public var fwClosable:Boolean = false;
public var tuveLiveW:liveWindow;
public var login:Login;
/* Initialization Routine */
public function init(mO:Object):Boolean {
/* Set Master Object */
masterObject = mO;
/* Initialize the AMF gateway */
gateway = new NetConnection();
gateway.connect("http://www.ubixonline.com/amfphp/gateway.php");
tvNetwork = new tuveNetwork();
tvNetwork.tvMaster = this;
ds = new DropShadowFilter(4,45,null,.75,4,4,1,3,false,false,false);
tvVidHolder.setActualSize(400, 300);
tvVidHolder.x = 580;
tvVidHolder.y = 5;
tvVidHolder.filters = [ds];
tvVid = new Video(400,300);
tvVidHolder.addChild(tvVid);
tvOverlay = new Image();
tvOverlay.width = 27;
tvOverlay.height = 25;
tvOverlay.source = "/images/tvOverLay.png";
tvVidHolder.addChild(tvOverlay);
tvNC = new NetConnection;
tvNC.addEventListener(NetStatusEvent.NET_STATUS, tvNetStatus);
tvNC.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
tvNC.client = this;
tvNC.objectEncoding = ObjectEncoding.AMF3;
tvNC.connect("rtmp://rtmp.ubixonline.com/oflaDemo");
topicHistory = new XMLList();
tvSO = SharedObject.getLocal("TUveINFO");
if (tvSO.data.myID == null)
tvSO.data.myID = new Date().getTime();
imWins = new Array();
myTimer.addEventListener(TimerEvent.TIMER,doCount);
return(true);
} /* End init */
private function doCount(event:TimerEvent):void {
myCount--;
var min:Number = Math.floor((myCount/60));
var sec:Number = (myCount%60);
var secStr:String;
if (sec < 10)
secStr = "0" + sec.toString();
else
secStr = sec.toString();
masterObject.tvTimer.text = "(" + min.toString() + ":" + secStr + ")";
}
public function onMetaData(info:Object):void {
if (tvGotMeta == false) {
if (tvStartTime > 0)
tvNS.seek(tvStartTime);
tvVid.width = info.width;
tvVid.height = info.height;
if ((300 - info.height) > 0) {
tvVid.y = ((300 - info.height)/2);
}
else {
tvVid.y = 0;
}
tvOverlay.y = tvVid.y + (tvVid.height - 29);
if ((400 - info.width) > 0) {
tvVid.x = ((400 - info.width)/2);
}
else {
tvVid.x = 0;
}
tvOverlay.x = tvVid.x + (tvVid.width - 31);
tvGotMeta = true;
}
}
public function onBWDone():void {
//Alert.show("Called BWDONE");
}
public function onPlayStatus(info:Object):void {
}
public function tvNetStatus(e:NetStatusEvent):void {
if (e.info.code == "NetConnection.Connect.Success") {
if (tvNS == null) {
tvNS = new NetStream(tvNC);
tvNS.client = this;
tvVid.attachNetStream(tvNS);
tvNS.close();
tvST = tvNS.soundTransform;
tvNS.addEventListener("netStatus", tvNetStatus);
}
}
else if (e.info.code == "NetConnection.Connect.Closed") {
tvNS.close();
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
Alert.show("securityError: " + event.text);
}
/* AMF Fault Handlers */
public function onFault(fault:String):void {
Alert.show("Error: " + fault.toString());
}
public function changeChannel(chan:String):void {
tvNetwork.sendData("PART " + currentChannel + "\n");
currentChannel = chan;//tvMaster.chanList[selChan.selectedIndex].@data;
tvNetwork.sendData("JOIN " + currentChannel + "\n");
userList = null;
userList = new XMLList();
}
public function validateNick(str:String):Boolean {
var pattern:RegExp = /^[a-zA-Z0-9]*$/;
var result:Object = pattern.exec(str);
if(result == null) {
return false;
}
return true;
}
public function parseCommand(command:String):void {
var dataArray:Array = command.split(" ");
var tmpString:String;
var i:Number;
switch (dataArray[0]) {
case "/topic":
tmpString = dataArray[1];
for (i=2;dataArray[i] != null;i++)
tmpString += " " + dataArray[i];
tvNetwork.sendData("TOPIC " + currentChannel + ":" + tmpString);
break;
case "/nick":
if (dataArray[1].length < 32) {
if (validateNick(dataArray[1]) == true)
tvNetwork.sendData("NICK " + dataArray[1]);
}
break;
case "/kick":
tmpString = dataArray[2];
for (i=3;dataArray[i] != null;i++)
tmpString += " " + dataArray[i];
tvNetwork.sendData("KICK " + currentChannel + ":" + dataArray[1] + ":" + tmpString + "\n");
break;
case "/me":
case "/em":
tmpString = dataArray[1];
for (i=2;dataArray[i] != null;i++)
tmpString += " " + dataArray[i];
tvNetwork.sendData("EMOTE " + currentChannel + ":" + tmpString + "\n");
masterObject.chatWindow.htmlText += "[" + new Date().toLocaleTimeString() + "] " + userName + " " + tmpString + "\n";
break;
case "/join":
tmpString = dataArray[1];
if (tmpString.indexOf("#") == 0) {
changeChannel(dataArray[1]);
}
else {
masterObject.chatWindow.htmlText += "Invalid Channel: " + dataArray[1] + "\n";
}
break;
case "/status":
tvNetwork.sendData("STATUS\n");
break;
case "/whois":
if (dataArray[1] != null)
tvNetwork.sendData("WHOIS " + dataArray[1] + "\n");
break;
case "/ban":
if (dataArray[1] != null)
if (dataArray[2] != null)
tvNetwork.sendData("BAN " + currentChannel + ":" + dataArray[1] + ":" + dataArray[2] + "\n");
else
tvNetwork.sendData("BAN " + currentChannel + ":" + dataArray[1] + ":300\n");
break;
case "/unban":
if (dataArray[1] != null)
tvNetwork.sendData("UNBAN " + currentChannel + ":" + dataArray[1] + "\n");
break;
case "/list":
tvNetwork.sendData("LIST\n");
break;
case "/s":
case "/search":
var searchOptV:Object = new Object();
searchOptV.sclass = Number(tvClass[masterObject.selC.selectedIndex].@data);
searchOptV.srating = Number(tvRating[masterObject.selR.selectedIndex].@data);
searchOptV.stime = masterObject.tvTime.text;
tmpString = dataArray[1];
for (i=2;dataArray[i] != null;i++)
tmpString += " " + dataArray[i];
searchOptV.skey = tmpString;
gateway.call("tuve.findSongs",new Responder(masterObject.getSongs,onFault),searchOptV);
break;
case "/msg":
tmpString = dataArray[2];
for (i=3;dataArray[i] != null;i++)
tmpString += " " + dataArray[i];
tvNetwork.sendData("MSG " + dataArray[1] + ":" + tmpString + "\n");
var tmpIM:imWindow;
tmpIM = findIM(dataArray[1]);
tmpIM.msgText.htmlText += "[" + new Date().toLocaleTimeString() + "] " + userName + ": " + tmpString;
break;
case "/clear":
masterObject.chatWindow.text = "";
break;
case "/my-secret":
tuveShowLiveW();
break;
default:
//Alert.show("Command: " + dataArray[0]);
break;
}
}
/* This function opens up a live broadcast window */
public function tuveShowLiveW():void {
if (tuveLiveW == null) {
tuveLiveW = new liveWindow();
tuveLiveW.tvMaster = this;
tuveLiveW.x = ((masterObject.width - tuveLiveW.width) / 2);
tuveLiveW.y = ((masterObject.height - tuveLiveW.height) /2 );
tuveLiveW.addEventListener("closeWindow",tuveCloseLiveW,false,0,true);
masterObject.addChild(tuveLiveW);
}
} /* End tuveShowLW() */
/* This function closes the channel list window */
public function tuveCloseLiveW(event:FlexEvent):void {
if (tuveLiveW != null) {
tuveLiveW.doUnInit();
masterObject.removeChild(tuveLiveW);
tuveLiveW = null;
}
} /* End tuveCloseLW */
/* This function opens up a channel list window */
public function tuveShowLW():void {
if (tuveLW == null) {
tuveLW = new listWindow();
tuveLW.tvMaster = this;
tuveLW.x = ((masterObject.width - tuveLW.width) / 2);
tuveLW.y = ((masterObject.height - tuveLW.height) /2 );
tuveLW.addEventListener("closeWindow",tuveCloseLW,false,0,true);
masterObject.addChild(tuveLW);
}
} /* End tuveShowLW() */
/* This function closes the channel list window */
public function tuveCloseLW(event:FlexEvent):void {
if (tuveLW != null) {
masterObject.removeChild(tuveLW);
tuveLW = null;
}
} /* End tuveCloseLW */
public function tuveCloseFW(event:FlexEvent):void {
if (tuveFW != null) {
if (fwClosable == true) {
masterObject.removeChild(tuveFW);
tuveFW = null;
}
}
}
public function tuveShowIW(vid:Number):void {
if (tuveIW == null) {
tuveIW = new infoWindow();
tuveIW.tvSizable = false;
tuveIW.tvMaster = this;
tuveIW.x = ((masterObject.width - tuveIW.width) / 2);
tuveIW.y = ((masterObject.height - tuveIW.height) /2 );
tuveIW.addEventListener("closeWindow",tuveCloseIW,false,0,true);
masterObject.addChild(tuveIW);
tuveIW.getInfo(vid);
}
else {
tuveIW.getInfo(vid);
}
} /* End invShow */
public function tuveCloseIW(event:FlexEvent):void {
if (tuveIW != null) {
masterObject.removeChild(tuveIW);
tuveIW = null;
}
}
public function tuveShowSW():void {
if (tuveSW == null) {
tuveSW = new searchWindow();
tuveSW.tvSizable = false;
tuveSW.tvMaster = this;
tuveSW.x = ((masterObject.width - tuveSW.width) / 2);
tuveSW.y = ((masterObject.height - tuveSW.height) /2 );
tuveSW.addEventListener("closeWindow",tuveCloseSW,false,0,true);
masterObject.addChild(tuveSW);
}
else {
tuveSW.carousel.reset(0);
}
} /* End invShow */
public function tuveCloseSW(event:FlexEvent):void {
if (tuveSW != null) {
masterObject.removeChild(tuveSW);
tuveSW = null;
}
}
public function setClip(tW:TextArea):void {
System.setClipboard(tW.text.substring(tW.selectionBeginIndex,tW.selectionEndIndex));
}
public function getInfo():void {
gateway.call("tuve.getInfo",new Responder(masterObject.getInfoRes,onFault),vid);
}
/*
*
* Private Message Functions
*
*/
public function sendIM(toNick:String,msg:String):void {
var tmpIM:imWindow;
tmpIM = findIM(toNick);
tmpIM.msgText.htmlText += "[" + new Date().toLocaleTimeString() + "] " + toNick + ": " + msg;
}
public function findIM(toNick:String):imWindow {
var i:Number;
var tmpIM:imWindow;
/* Check to see if we have an open IM already */
for (i=0;i<imWins.length;i++) {
tmpIM = imWins[i];
if (tmpIM.toNick.toLocaleLowerCase().match(toNick.toLocaleLowerCase()))
return(tmpIM);
}
/* Create a new IM if there is no existing one */
tmpIM = new imWindow();
tmpIM.toNick = toNick;
tmpIM.tvMaster = this;
tmpIM.addEventListener("closeWindow",imClose,false,0,true);
tmpIM.title = "IM: " + toNick;
imWins.push(tmpIM);
tmpIM.x = (masterObject.width/2) - (tmpIM.width/2);
tmpIM.y = (masterObject.height/2) - (tmpIM.height/2);
masterObject.addChild(tmpIM);
return(tmpIM);
}
/* This function closes an IM window */
private function imClose(event:FlexEvent):void {
var toNick:String = (event.currentTarget as imWindow).toNick;
var i:Number;
var tmpIM:imWindow;
var tmpArray:Array = new Array();
for (i=0;i < imWins.length;i++) {
tmpIM = imWins[i];
if (tmpIM.toNick.match(toNick)) {
masterObject.removeChild(tmpIM);
tmpIM = null;
}
else
tmpArray.push(imWins[i]);
}
imWins = null;
imWins = tmpArray;
} /* End imClose() */
/* End Private Message Functions */
/*
*
* Authentication Functions
*
*/
public function doLogin():void {
if (login == null) {
login = PopUpManager.createPopUp(this.masterObject as Application,Login,true) as Login;
login.funcs = this;
login.tvMaster = this;
if (tvSO.data.userName != null)
login.username.text = tvSO.data.userName;
PopUpManager.centerPopUp(login);
}
} /* End doLogin() */
public function authUser(userN:String,channel:String):void {
userName = userN;
tvSO.data.userName = userN;
currentChannel = channel;
tvNetwork.init();
} /* End authUser(userName,channel); */
public function authFail(error:String):void {
doLogin();
login.logErr.text = "Error: " + error;
login.loginButton.enabled = true;
} /* End authFail(error) */
public function authSuccess():void {
PopUpManager.removePopUp(login);
login = null;
if (tvSO.data.volume != null)
masterObject.volume.value = tvSO.data.volume;
masterObject.updateVolume();
} /* End authSuccess() */
/* End Authentication Functions */
} /* End Master */
} /* End package */