//serverless-webrtc

//JavaScript memory game, only transfer code
function xxx()
{
var that = this;
this.cfg = {
	conn:	{
		iceServers: [{url: 'stun:stun.l.google.com:19302'}]
		},
	channel: [{
		type: 'textMessages',
		opt: {
			ordered: false,
			maxRetransmitTime: 1000
			},
		}],		
	room: "signaling"
	};
this.api = {};
this.api.peer    = window.RTCPeerConnection     || window.mozRTCPeerConnection     || window.webkitRTCPeerConnection     || window.msRTCPeerConnection;
this.api.session = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.msRTCSessionDescription;
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia;
// navigator.getUserMedia({ "audio": true, "video": true }, ...)
this.conn    = null;
this.channel = [];
this.connect = function()
	{
	//var conn, channel;
	try {
		that.conn    = new that.api.peer(that.cfg.conn, null);
	} catch (e) {
		console.log("Error: Failed to create PeerConnection, exception: " + e.message);
		alert("Error: Cannot create RTCPeerConnection object; WebRTC is not supported by this browser.");
		return;
	}
	that.channel[0] = that.conn.createDataChannel(that.cfg.channel[0].type, that.cfg.channel[0].opt);
        that.conn.ondatachannel = pp_receiveDataChannel;
//*
        that.conn.onicecandidate = function (event)
		{
//                if (event.candidate)
  //                      io.emit('signal',{"type":"ice candidate", "message": JSON.stringify({ 'candidate': event.candidate }), "room":SIGNAL_ROOM});
	        that.send(JSON.stringify({ "candidate": event.candidate }));

    if (event.candidate) {
      sendMessage({
	type: 'candidate',
        label    : event.candidate.sdpMLineIndex,
        id       : event.candidate.sdpMid,
        candidate: event.candidate.candidate
	});
    } else {
      console.log("End of candidates.");
    }

	        };
//  pc.onconnecting = onSessionConnecting;
//  pc.onopen = onSessionOpened;
//  pc.onaddstream = onRemoteStreamAdded;
//  pc.onremovestream = onRemoteStreamRemoved;
	that.conn.onnegotiationneeded = function ()
		{
                conn.createOffer(sendLocalDesc, logError);
	        }
	that.channel[0].onerror = function (error) {
		console.log("Error: Data Channel Error:", error);
		};
	that.channel[0].onmessage = function (event) {
		if (!that.conn)
			{that.connect();}
/*
    var signal = JSON.parse(evt.data);
    if (signal.sdp)
        pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
    else
        pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
*/
		console.log("Notice: Got Data Channel Message:", event.data);
		};
	that.channel[0].onopen = function () {
		dataChannel.send("Hello World!");
		};
	that.channel[0].onclose = function () {
		console.log("Notice: The Data Channel is Closed");
		};
//onclick:			that.channel[0].send(data_str);
	//that.conn    = conn;
	//that.channel = channel;
	}
	
}
function sendMessage(message) {
  var msgString = JSON.stringify(message);
  console.log('C->S: ' + msgString);
  path = '/message?r=99688636' + '&u=92246248';
  var xhr = new XMLHttpRequest();
  xhr.open('POST', path, true);
  xhr.send(msgString);
}


//Page controls
var chatArea = document.querySelector("#chatArea");
var signalingArea = document.querySelector("#signalingArea");

//Signaling Code Setup
var SIGNAL_ROOM = "signaling";


////
io = io.connect();
 
io.emit('ready', {"signal_room": SIGNAL_ROOM});
 
//Send a first signaling message to anyone listening
 
//In other apps this would be on a button click, we are just doing it on page load
 
io.emit('signal',{"type":"user_here", "message":"Would you like to play a game?", "room":SIGNAL_ROOM});
io.on('signaling_message', function(data) {
        //Setup the RTC Peer Connection object
        if (!rtcPeerConn)
                startSignaling();
        if (data.type != "user_here") {
 
                var message = JSON.parse(data.message);
                if (message.sdp) {
                        rtcPeerConn.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
 
                                // if we received an offer, we need to answer
                                if (rtcPeerConn.remoteDescription.type == 'offer') {
 
                                        rtcPeerConn.createAnswer(sendLocalDesc, logError);
                                }
                        }, logError);
                }
                else {
                        rtcPeerConn.addIceCandidate(new RTCIceCandidate(message.candidate));
                }
        }        
 
});

function sendLocalDesc(desc) {
        rtcPeerConn.setLocalDescription(desc, function () {
                io.emit('signal',{"type":"SDP", "message": JSON.stringify({ 'sdp': rtcPeerConn.localDescription }), "room":SIGNAL_ROOM});
 
        }, logError);
}







///-------------------
/*
This code was developed by @ArinSime and WebRTC.ventures for a WebRTC blog post.  
You are welcome to use it at your own risk as starter code for your applications, 
but please be aware that this is not a complete code example with all the necessary 
security and privacy considerations implemented that a production app would require.  
It is for educational purposes only, and any other use is done at your own risk.
*/

//datachannel.js:  This file contains the WebRTC and DataChannel specific code

//Page controls
var chatArea = document.querySelector("#chatArea");
var signalingArea = document.querySelector("#signalingArea");

//Signaling Code Setup
var SIGNAL_ROOM = "signaling";
var configuration = {
	'iceServers': [{
		'url': 'stun:stun.l.google.com:19302'
	}]
};
var rtcPeerConn;
var dataChannelOptions = {
	ordered: false, //no guaranteed delivery, unreliable but faster 
	maxRetransmitTime: 1000, //milliseconds
};
var dataChannel;

io = io.connect();
io.emit('ready', {"signal_room": SIGNAL_ROOM});

//Send a first signaling message to anyone listening
//In other apps this would be on a button click, we are just doing it on page load
io.emit('signal',{"type":"user_here", "message":"Would you like to play a game?", "room":SIGNAL_ROOM});

io.on('signaling_message', function(data) {
	displaySignalMessage("Signal received: " + data.type);
	//Setup the RTC Peer Connection object
	if (!rtcPeerConn)
		startSignaling();
	
	if (data.type != "user_here") {
		var message = JSON.parse(data.message);
		if (message.sdp) {
			rtcPeerConn.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
				// if we received an offer, we need to answer
				if (rtcPeerConn.remoteDescription.type == 'offer') {
					rtcPeerConn.createAnswer(sendLocalDesc, logError);
				}
			}, logError);
		}
		else {
			rtcPeerConn.addIceCandidate(new RTCIceCandidate(message.candidate));
		}
	}
	
});

function startSignaling() {
	displaySignalMessage("starting signaling...");
	rtcPeerConn = new webkitRTCPeerConnection(configuration, null);
	dataChannel = rtcPeerConn.createDataChannel('textMessages', dataChannelOptions);
				
	dataChannel.onopen = dataChannelStateChanged;
	rtcPeerConn.ondatachannel = receiveDataChannel;
	
	// send any ice candidates to the other peer
	rtcPeerConn.onicecandidate = function (evt) {
		if (evt.candidate)
			io.emit('signal',{"type":"ice candidate", "message": JSON.stringify({ 'candidate': evt.candidate }), "room":SIGNAL_ROOM});
		displaySignalMessage("completed that ice candidate...");
	};
	
	// let the 'negotiationneeded' event trigger offer generation
	rtcPeerConn.onnegotiationneeded = function () {
		displaySignalMessage("on negotiation called");
		rtcPeerConn.createOffer(sendLocalDesc, logError);
	}  
}

function sendLocalDesc(desc) {
	rtcPeerConn.setLocalDescription(desc, function () {
		displaySignalMessage("sending local description");
		io.emit('signal',{"type":"SDP", "message": JSON.stringify({ 'sdp': rtcPeerConn.localDescription }), "room":SIGNAL_ROOM});
	}, logError);
}

//Data Channel Specific methods
function dataChannelStateChanged() {
	if (dataChannel.readyState === 'open') {
		displaySignalMessage("Data Channel open");
		dataChannel.onmessage = receiveDataChannelMessage;
	}
}

function receiveDataChannel(event) {
	displaySignalMessage("Receiving a data channel");
	dataChannel = event.channel;
	dataChannel.onmessage = receiveDataChannelMessage;
}

function receiveDataChannelMessage(event) {
	displayMessage("From DataChannel: " + event.data);
	
	if (event.data.split(" ")[0] == "memoryFlipTile") {
		var tileToFlip = event.data.split(" ")[1];
		displayMessage("Flipping tile " + tileToFlip);
		var tile = document.querySelector("#" + tileToFlip);
		var index = tileToFlip.split("_")[1];
		var tile_value = memory_array[index];
		flipTheTile(tile,tile_value);
	} else if (event.data.split(" ")[0] == "newBoard") {
		displayMessage("Setting up new board");
		memory_array = event.data.split(" ")[1].split(",");
		newBoard();
	}
	
}

//Logging/Display Methods
function logError(error) {
	displaySignalMessage(error.name + ': ' + error.message);
}

function displayMessage(message) {
	chatArea.innerHTML = chatArea.innerHTML + "<br/>" + message;
}

function displaySignalMessage(message) {
	signalingArea.innerHTML = signalingArea.innerHTML + "<br/>" + message;
}
///-------------------

function startSignaling() {
        rtcPeerConn = new webkitRTCPeerConnection(configuration, null);
        dataChannel = rtcPeerConn.createDataChannel('textMessages', dataChannelOptions);
        dataChannel.onopen = dataChannelStateChanged;
        rtcPeerConn.ondatachannel = receiveDataChannel;
 
        // send any ice candidates to the other peer
        rtcPeerConn.onicecandidate = function (evt) {
                if (evt.candidate)
                        io.emit('signal',{"type":"ice candidate", "message": JSON.stringify({ 'candidate': evt.candidate }), "room":SIGNAL_ROOM});
 
        };
 
        // let the 'negotiationneeded' event trigger offer generation
        rtcPeerConn.onnegotiationneeded = function () {
                rtcPeerConn.createOffer(sendLocalDesc, logError);
        }  
}
 
 
function sendLocalDesc(desc) {
        rtcPeerConn.setLocalDescription(desc, function () {
                io.emit('signal',{"type":"SDP", "message": JSON.stringify({ 'sdp': rtcPeerConn.localDescription }), "room":SIGNAL_ROOM});
 
        }, logError);
}



////////////////////


io.on('signaling_message', function(data) {
        //Setup the RTC Peer Connection object
        if (!rtcPeerConn)
                startSignaling();
        if (data.type != "user_here") {
 
                var message = JSON.parse(data.message);
                if (message.sdp) {
                        rtcPeerConn.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
 
                                // if we received an offer, we need to answer
                                if (rtcPeerConn.remoteDescription.type == 'offer') {
 
                                        rtcPeerConn.createAnswer(sendLocalDesc, logError);
                                }
                        }, logError);
                }
                else {
                        rtcPeerConn.addIceCandidate(new RTCIceCandidate(message.candidate));
                }
        }        
 
});

////
io = io.connect();
 
io.emit('ready', {"signal_room": SIGNAL_ROOM});
 
//Send a first signaling message to anyone listening
 
//In other apps this would be on a button click, we are just doing it on page load
 
io.emit('signal',{"type":"user_here", "message":"Would you like to play a game?", "room":SIGNAL_ROOM});

//////////////

rtcPeerConn = new webkitRTCPeerConnection(configuration, null);
dataChannel = rtcPeerConn.createDataChannel('textMessages', dataChannelOptions);
 
dataChannel.onopen = dataChannelStateChanged;
rtcPeerConn.ondatachannel = receiveDataChannel;

///////////////

function dataChannelStateChanged() {
        if (dataChannel.readyState === 'open') {
                dataChannel.onmessage = receiveDataChannelMessage;
        }
}
 
function receiveDataChannel(event) {
        dataChannel = event.channel;
        dataChannel.onmessage = receiveDataChannelMessage;
}

////////
function receiveDataChannelMessage(event) {        
        if (event.data.split(" ")[0] == "memoryFlipTile") {
                var tileToFlip = event.data.split(" ")[1];
                displayMessage("Flipping tile " + tileToFlip);
                var tile = document.querySelector("#" + tileToFlip);
                var index = tileToFlip.split("_")[1];
                var tile_value = memory_array[index];
                flipTheTile(tile,tile_value);
        } else if (event.data.split(" ")[0] == "newBoard") {
                displayMessage("Setting up new board");
                memory_array = event.data.split(" ")[1].split(",");
                newBoard();
        }
}

/////////

function memoryFlipTile(tile,val){
        dataChannel.send("memoryFlipTile " + tile.id);
        flipTheTile(tile,val);
}

////////

var setupBoard = document.querySelector("#setupBoard");
 
setupBoard.addEventListener('click', function(ev){
        memory_array.memory_tile_shuffle();
        newBoard();
        dataChannel.send("newBoard " + memory_array.toString());
        ev.preventDefault();
 
}, false);

///////////