package com.voxeo.moho.remote.impl;
import java.util.Map;
import java.util.Properties;
import javax.media.mscontrol.MediaObject;
import javax.media.mscontrol.join.Joinable.Direction;
import javax.media.mscontrol.join.JoinableStream;
import javax.media.mscontrol.join.JoinableStream.StreamType;
import com.rayo.core.JoinDestinationType;
import com.rayo.core.JoinedEvent;
import com.rayo.core.StartedSpeakingEvent;
import com.rayo.core.UnjoinedEvent;
import com.voxeo.moho.Call;
import com.voxeo.moho.Endpoint;
import com.voxeo.moho.Joint;
import com.voxeo.moho.MediaService;
import com.voxeo.moho.Mixer;
import com.voxeo.moho.Participant;
import com.voxeo.moho.Unjoint;
import com.voxeo.moho.common.event.MohoActiveSpeakerEvent;
import com.voxeo.moho.common.event.MohoJoinCompleteEvent;
import com.voxeo.moho.common.event.MohoUnjoinCompleteEvent;
import com.voxeo.moho.event.JoinCompleteEvent;
import com.voxeo.moho.event.UnjoinCompleteEvent;
import com.voxeo.moho.remote.MohoRemoteException;
import com.voxeo.rayo.client.xmpp.stanza.Presence;
public class MixerImpl extends MediaServiceSupport<Mixer> implements Mixer {
private MixerEndpointImpl _mixerEndpoint;
protected Map<Object, Object> _params;
protected String _name;
public MixerImpl(MixerEndpointImpl mixerEndpoint, String name, Map<Object, Object> params) {
super(mixerEndpoint.getMohoRemote());
_mixerEndpoint = mixerEndpoint;
_params = params;
_id = name;
_mohoRemote.addParticipant(this);
_name = name;
}
@Override
public JoinableStream getJoinableStream(StreamType value) {
throw new UnsupportedOperationException(Constants.unsupported_operation);
}
@Override
public JoinableStream[] getJoinableStreams() {
throw new UnsupportedOperationException(Constants.unsupported_operation);
}
@Override
public Endpoint getAddress() {
return _mixerEndpoint;
}
@Override
public Joint join(Participant other, JoinType type, Direction direction) {
return this.join(other, type, false, direction);
}
@Override
public Joint join(Participant other, JoinType type, boolean force, Direction direction) {
Joint joint = null;
if (other instanceof CallImpl) {
joint = other.join(this, type, reserve(direction));
return joint;
}
else {
// TODO mixer join mixer
}
return joint;
}
private Direction reserve(Direction direction) {
if (direction == Direction.RECV) {
return Direction.SEND;
}
else if (direction == Direction.SEND) {
return Direction.RECV;
}
return Direction.DUPLEX;
}
@Override
public Unjoint unjoin(Participant other) {
if (!_joinees.contains(other)) {
throw new IllegalStateException("Not joined.");
}
Unjoint unjoint = null;
if (other instanceof CallImpl) {
unjoint = other.unjoin(this);
}
return unjoint;
}
@Override
public Participant[] getParticipants() {
return _joinees.getJoinees();
}
@Override
public Participant[] getParticipants(Direction direction) {
return _joinees.getJoinees(direction);
}
@Override
public void disconnect() {
_joinees.clear();
}
@Override
public MediaObject getMediaObject() {
throw new UnsupportedOperationException(Constants.unsupported_operation);
}
@Override
public String getRemoteAddress() {
return _id;
}
@Override
public MediaService<Mixer> getMediaService() {
throw new UnsupportedOperationException(Constants.unsupported_operation);
}
@Override
public Joint join(Participant other, JoinType type, Direction direction, Properties props) {
return join(other, type, false, direction, props);
}
@Override
public Joint join(Participant other, JoinType type, boolean force, Direction direction, Properties props) {
//TODO rayo support dtmfpassthrough?
return join(other, type, direction);
}
@Override
public Joint join(Participant other, JoinType type, boolean force, Direction direction, boolean dtmfPassThough) {
//TODO rayo support dtmfpassthrough?
return join(other, type, direction);
}
@Override
public JoinType getJoinType(Participant participant) {
return _joinees.getJoinType(participant);
}
@Override
public void onRayoEvent(JID from, Presence presence) {
LOG.debug("MixerImpl Recived presence, processing:" + presence);
Object object = presence.getExtension().getObject();
if (object instanceof JoinedEvent) {
MohoJoinCompleteEvent mohoEvent = null;
JoinedEvent event = (JoinedEvent) object;
String id = event.getTo();
JoinDestinationType type = event.getType();
JointImpl joint = _joints.remove(id);
if (type == JoinDestinationType.CALL) {
Call peer = (Call) _mohoRemote.getParticipant(id);
_joinees.add(peer, joint.getType(), joint.getDirection());
mohoEvent = new MohoJoinCompleteEvent(this, peer, JoinCompleteEvent.Cause.JOINED, true);
}
else {
// TODO support mixer join mixer
}
this.dispatch(mohoEvent);
}
else if (object instanceof UnjoinedEvent) {
UnjoinedEvent event = (UnjoinedEvent) object;
MohoUnjoinCompleteEvent mohoEvent = null;
String id = event.getFrom();
JoinDestinationType type = event.getType();
_unjoints.remove(id);
if (type == JoinDestinationType.CALL) {
Call peer = (Call) _mohoRemote.getParticipant(id);
_joinees.remove(peer);
mohoEvent = new MohoUnjoinCompleteEvent(this, peer, UnjoinCompleteEvent.Cause.SUCCESS_UNJOIN, true);
}
else {
// TODO mixer unjoin mixer
}
this.dispatch(mohoEvent);
}
else if (object instanceof StartedSpeakingEvent) {
StartedSpeakingEvent event = (StartedSpeakingEvent) object;
Call speaker = (Call) _mohoRemote.getParticipant(event.getSpeakerId());
MohoActiveSpeakerEvent mohoEvent = new MohoActiveSpeakerEvent(this, new Participant[] {speaker});
this.dispatch(mohoEvent);
}
}
@Override
public String startJoin() throws MohoRemoteException {
return _id;
}
@Override
public String getName() {
return _name;
}
}