/**
   * Fired when call state changes
   *
   * @param evt CallStateEvent
   */
  public void callStateChanged(CallStateEvent evt) {
    try {

      for (SoftPhoneListener sfl : softPhoneListeners) {
        sfl.callStateChanged(evt);
      }

      Call call = evt.getSourceCall();
      Log.debug("callStateChanged", evt.getOldState() + " -> " + evt.getNewState());
      if (evt.getNewState() == Call.CONNECTED) {
        // sipManager.setBusy(true);

        if (call.getAudioReceiverChannel() != null) call.getAudioReceiverChannel().stop();

        if (evt.getOldState() == Call.MOVING_REMOTELY) {
          AudioMediaSession audioMediaSession = evt.getSourceCall().getAudioMediaSession();
          if (call.getAudioReceiverChannel() != null) call.getAudioReceiverChannel().stop();

          if (audioMediaSession != null) {
            audioMediaSession.stopTrasmit();
            audioMediaSession.stopReceive();
          }
          VideoMediaSession videoMediaSession = evt.getSourceCall().getVideoMediaSession();
          if (videoMediaSession != null) {
            videoMediaSession.stopTrasmit();
            videoMediaSession.stopReceive();
          }
          PhoneManager.setUsingMediaLocator(false);
        }

        int localAudioPort = -1;
        int localVideoPort = -1;

        Vector<MediaDescription> mediaDescriptions =
            call.getLocalSdpDescription().getMediaDescriptions(true);
        for (MediaDescription mediaDescription : mediaDescriptions) {
          if (mediaDescription.getMedia().getMediaType().equals("audio"))
            localAudioPort = mediaDescription.getMedia().getMediaPort();
          else if (mediaDescription.getMedia().getMediaType().equals("video"))
            localVideoPort = mediaDescription.getMedia().getMediaPort();
        }

        AudioMediaSession audioMediaSession =
            mediaManager.createAudioMediaSession(
                call.getRemoteSdpDescription().toString(), localAudioPort);
        call.setAudioMediaSession(audioMediaSession);

        if (audioMediaSession != null) {
          audioMediaSession.startTrasmit();
          audioMediaSession.startReceive();
        }

        // If remote client have video
        if (localVideoPort > 0) {
          if (SettingsManager.getLocalPreferences().getVideoDevice() != null
              && !"".equals(SettingsManager.getLocalPreferences().getVideoDevice())) {
            VideoMediaSession videoMediaSession =
                mediaManager.createVideoMediaSession(
                    call.getRemoteSdpDescription().toString(), localVideoPort);
            if (videoMediaSession != null) {
              videoMediaSession.startTrasmit();
              videoMediaSession.startReceive();
              call.setVideoMediaSession(videoMediaSession);
            }
          }
        }

        evt.getSourceCall().start();

        Log.debug("MEDIA STREAMS OPENED");

      } else if (evt.getNewState() == Call.RINGING) {

        if (call.getRemoteSdpDescription() != null && !call.getRemoteSdpDescription().equals("")) {

          Log.debug("STATE", call.getRemoteSdpDescription().toString());

          int localPort =
              ((MediaDescription) (call.getLocalSdpDescription().getMediaDescriptions(true).get(0)))
                  .getMedia()
                  .getMediaPort();
          int destPort =
              ((MediaDescription)
                      (call.getRemoteSdpDescription().getMediaDescriptions(true).get(0)))
                  .getMedia()
                  .getMediaPort();
          String destIp = call.getRemoteSdpDescription().getConnection().getAddress();

          AudioReceiverChannel audioReceiverChannel =
              mediaManager.createAudioReceiverChannel(localPort, destIp, destPort, (destPort + 1));
          call.setAudioReceiverChannel(audioReceiverChannel);

          if (audioReceiverChannel != null) audioReceiverChannel.start();
        }

      } else if (evt.getNewState() == Call.DISCONNECTED) {
        sipManager.setBusy(false);

        AudioMediaSession audioMediaSession = evt.getSourceCall().getAudioMediaSession();
        if (audioMediaSession != null) {
          audioMediaSession.stopTrasmit();
          audioMediaSession.stopReceive();
        }
        if (call.getAudioReceiverChannel() != null) call.getAudioReceiverChannel().stop();
        VideoMediaSession videoMediaSession = evt.getSourceCall().getVideoMediaSession();
        if (videoMediaSession != null) {
          videoMediaSession.stopTrasmit();
          videoMediaSession.stopReceive();
        }

        PhoneManager.setUsingMediaLocator(false);

      } else if (evt.getNewState() == Call.FAILED) {
        call.setState(Call.DISCONNECTED);
        if (call.getAudioReceiverChannel() != null) call.getAudioReceiverChannel().stop();

        CallRejectedEvent rejectEvt =
            new CallRejectedEvent("Disconnected", call.getLastRequest(), call);

        for (SoftPhoneListener softPhoneListener : softPhoneListeners) {
          softPhoneListener.callRejectedRemotely(rejectEvt);
        }

        PhoneManager.setUsingMediaLocator(false);
      }
    } catch (Exception e) {
      Log.error("callStateChanged", e);
    }
  }