(function ($) {
	$(document).ready(function() {
    var copuloo_tokenUrl = CopulooBrowserCallingVars.tokenUrl;
    var copuloo_userID = CopulooBrowserCallingVars.userID;
		var copuloo_user_nonce = CopulooBrowserCallingVars.user_nonce;
	  const speakerDevices = document.getElementById("speaker-devices");
	  const ringtoneDevices = document.getElementById("ringtone-devices");
	  const outputVolumeBar = document.getElementById("output-volume");
	  const inputVolumeBar = document.getElementById("input-volume");
	  const volumeIndicators = document.getElementById("volume-indicators");
	  const callButton = document.getElementById("button-call");
	  const outgoingCallHangupButton = document.getElementById("button-hangup-outgoing");
	  const callControlsDiv = document.getElementById("call-controls");
	  const audioSelectionDiv = document.getElementById("output-selection");
	  const getAudioDevicesButton = document.getElementById("get-devices");
	  const logDiv = document.getElementById("logText");
	  const incomingCallDiv = document.getElementById("incoming-call");
	  const incomingCallHangupButton = document.getElementById("button-hangup-incoming");
	  const incomingCallAcceptButton = document.getElementById("button-accept-incoming");
	  const incomingCallRejectButton = document.getElementById("button-reject-incoming");
	  const phoneNumberCountryCode = document.getElementById("country-code-outbound");
	  const phoneNumberInput = document.getElementById("phone-number");
	  const incomingPhoneNumberEl = document.getElementById("incoming-number");
	  const startupButton = document.getElementById("startup-button");

	  let device;
	  let token;
	  startupClient();

	  // Event Listeners
	  callButton.onclick = (e) => {
	    e.preventDefault();
	    makeOutgoingCall();
	  };
	  getAudioDevicesButton.onclick = getAudioDevices;
	  speakerDevices.addEventListener("change", updateOutputDevice);
	  ringtoneDevices.addEventListener("change", updateRingtoneDevice);

	  // SETUP STEP 1:
	  // Browser client should be started after a user gesture
	  // to avoid errors in the browser console re: AudioContext
	  //startupButton.addEventListener("click", startupClient());

	  // SETUP STEP 2: Request an Access Token
	  async function startupClient() {
	    try {
	      const data = await $.ajax({
	            url: copuloo_tokenUrl,
	            method: 'POST',
	            dataType: 'json', // Expect a JSON response
	            data: { action: 'copuloo_browser_token', user_nonce: copuloo_user_nonce }
	        });
	      token = data.token;
	      //setClientNameUI(data.identity);
	      intitializeDevice();
	    } catch (err) {
	      console.log(err); // Log error in browser console
	      //alert("Unable to setup browser inbound and outbound calls.");
	    }
	  }

	  // SETUP STEP 3:
	  // Instantiate a new Twilio.Device
	  function intitializeDevice() {
	    //logDiv.classList.remove("hide");
	    device = new Twilio.Device(token, {
	      logLevel: 1,
	      // Set Opus as our preferred codec. Opus generally performs better, requiring less bandwidth and
	      // providing better audio quality in restrained network conditions.
	      codecPreferences: ["opus", "pcmu"]
	    });

	    addDeviceListeners(device);

	    // Device must be registered in order to receive incoming calls
	    device.register();
	  }

	  // SETUP STEP 4:
	  // Listen for Twilio.Device states
	  function addDeviceListeners(device) {
	    device.on("registered", function () {
	      log("Ready to make and receive calls!");
	      callControlsDiv.classList.remove("hide");
	    });

	    device.on("error", function (error) {
	      log("Error: " + error.message);
	    });

	    device.on("incoming", handleIncomingCall);

	    device.audio.on("deviceChange", updateAllAudioDevices.bind(device));

	    // Show audio selection UI if it is supported by the browser.
	    if (device.audio.isOutputSelectionSupported) {
	      audioSelectionDiv.classList.remove("hide");
	    }
	  }

	  // MAKE AN OUTGOING CALL

	  async function makeOutgoingCall() {
	    var params = {
	      // get the phone number to call from the DOM
	      To_code: phoneNumberCountryCode.value,
		  To_number: phoneNumberInput.value,
	      User: copuloo_userID,
		  user_nonce: copuloo_user_nonce,
	      BrowserOutgoing: 'true',
	    };

	    if (device) {
	      log(`Attempting to call phone number ...`);

	      // Twilio.Device.connect() returns a Call object
	      const call = await device.connect({ params });

	      // add listeners to the Call
	      // "accepted" means the call has finished connecting and the state is now "open"
	      call.on("accept", updateUIAcceptedOutgoingCall);
	      call.on("disconnect", updateUIDisconnectedOutgoingCall);
	      call.on("cancel", updateUIDisconnectedOutgoingCall);

	      outgoingCallHangupButton.onclick = () => {
	        log("Hanging up ...");
	        call.disconnect();
	      };

	    } else {
	      log("Unable to make call.");
	    }
	  }

	  function updateUIAcceptedOutgoingCall(call) {
	    log("Call in progress ...");
	    callButton.disabled = true;
	    outgoingCallHangupButton.classList.remove("hide");
	    volumeIndicators.classList.remove("hide");
	    bindVolumeIndicators(call);
	  }

	  function updateUIDisconnectedOutgoingCall() {
	    log("Call disconnected.");
	    callButton.disabled = false;
	    outgoingCallHangupButton.classList.add("hide");
	    volumeIndicators.classList.add("hide");
	  }

	  // HANDLE INCOMING CALL

	  function handleIncomingCall(call) {
	    log(`Incoming call from ${call.parameters.From}`);
	    $("#during_call").modal("show");

	    //show incoming call div and incoming phone number
	    incomingCallDiv.classList.remove("hide");
	    incomingPhoneNumberEl.innerHTML = call.parameters.From;

	    //add event listeners for Accept, Reject, and Hangup buttons
	    incomingCallAcceptButton.onclick = () => {
	      acceptIncomingCall(call);
	    };

	    incomingCallRejectButton.onclick = () => {
	      rejectIncomingCall(call);
	    };

	    incomingCallHangupButton.onclick = () => {
	      hangupIncomingCall(call);
	    };

	    // add event listener to call object
	    call.on("cancel", handleDisconnectedIncomingCall);
	    call.on("disconnect", handleDisconnectedIncomingCall);
	    call.on("reject", handleDisconnectedIncomingCall);
	  }

	  // ACCEPT INCOMING CALL

	  function acceptIncomingCall(call) {
	    call.accept();

	    //update UI
	    log("Accepted incoming call.");
	    incomingCallAcceptButton.classList.add("hide");
	    incomingCallRejectButton.classList.add("hide");
	    incomingCallHangupButton.classList.remove("hide");
	  }

	  // REJECT INCOMING CALL

	  function rejectIncomingCall(call) {
	    call.reject();
	    log("Rejected incoming call");
	    resetIncomingCallUI();
	  }

	  // HANG UP INCOMING CALL

	  function hangupIncomingCall(call) {
	    call.disconnect();
	    log("Hanging up incoming call");
	    resetIncomingCallUI();
	  }

	  // HANDLE CANCELLED INCOMING CALL

	  function handleDisconnectedIncomingCall() {
	    log("Incoming call ended.");
	    resetIncomingCallUI();
	  }

	  // MISC USER INTERFACE

	  // Activity log
	  function log(message) {
	    logDiv.innerHTML = `${message}`;
	  }

	  function setClientNameUI(clientName) {
	    var div = document.getElementById("client-name");
	    div.innerHTML = `Your client name: <strong>${clientName}</strong>`;
	  }

	  function resetIncomingCallUI() {
	    incomingPhoneNumberEl.innerHTML = "";
	    incomingCallAcceptButton.classList.remove("hide");
	    incomingCallRejectButton.classList.remove("hide");
	    incomingCallHangupButton.classList.add("hide");
	    incomingCallDiv.classList.add("hide");
	  }

	  // AUDIO CONTROLS

	  async function getAudioDevices() {
	    await navigator.mediaDevices.getUserMedia({ audio: true });
	    updateAllAudioDevices.bind(device);
	  }

	  function updateAllAudioDevices() {
	    if (device) {
	      updateDevices(speakerDevices, device.audio.speakerDevices.get());
	      updateDevices(ringtoneDevices, device.audio.ringtoneDevices.get());
	    }
	  }

	  function updateOutputDevice() {
	    const selectedDevices = Array.from(speakerDevices.children)
	      .filter((node) => node.selected)
	      .map((node) => node.getAttribute("data-id"));

	    device.audio.speakerDevices.set(selectedDevices);
	  }

	  function updateRingtoneDevice() {
	    const selectedDevices = Array.from(ringtoneDevices.children)
	      .filter((node) => node.selected)
	      .map((node) => node.getAttribute("data-id"));

	    device.audio.ringtoneDevices.set(selectedDevices);
	  }

	  function bindVolumeIndicators(call) {
	    call.on("volume", function (inputVolume, outputVolume) {
	      var inputColor = "red";
	      if (inputVolume < 0.5) {
	        inputColor = "green";
	      } else if (inputVolume < 0.75) {
	        inputColor = "yellow";
	      }

	      inputVolumeBar.style.width = Math.floor(inputVolume * 300) + "px";
	      inputVolumeBar.style.background = inputColor;

	      var outputColor = "red";
	      if (outputVolume < 0.5) {
	        outputColor = "green";
	      } else if (outputVolume < 0.75) {
	        outputColor = "yellow";
	      }

	      outputVolumeBar.style.width = Math.floor(outputVolume * 300) + "px";
	      outputVolumeBar.style.background = outputColor;
	    });
	  }

	  // Update the available ringtone and speaker devices
	  function updateDevices(selectEl, selectedDevices) {
	    selectEl.innerHTML = "";

	    device.audio.availableOutputDevices.forEach(function (device, id) {
	      var isActive = selectedDevices.size === 0 && id === "default";
	      selectedDevices.forEach(function (device) {
	        if (device.deviceId === id) {
	          isActive = true;
	        }
	      });

	      var option = document.createElement("option");
	      option.label = device.label;
	      option.setAttribute("data-id", id);
	      if (isActive) {
	        option.setAttribute("selected", "selected");
	      }
	      selectEl.appendChild(option);
	    });
	  }
		});
	})(jQuery);

function rangeChange(value) {
  document.getElementById('rangeValue').value = value;
}
// tz database time zones
(function() {
  document.getElementById('timezoneEmptyOption').value = Intl.DateTimeFormat().resolvedOptions().timeZone;
  document.getElementById('timezoneEmptyOption').innerHTML = Intl.DateTimeFormat().resolvedOptions().timeZone + ' - Based On Your Location';
})();
// Switch from open to closed
function changeStatus(dayOfTheWeek) {
  if (document.getElementById(dayOfTheWeek).classList.contains("badge-danger")) {
    document.getElementById(dayOfTheWeek).classList.replace("badge-danger", "badge-success");
    document.getElementById(dayOfTheWeek).innerHTML = "Open";
    document.getElementById(dayOfTheWeek + '_status').value = "1";
    document.getElementById(dayOfTheWeek + '1').readOnly = false;
    document.getElementById(dayOfTheWeek + '2').readOnly = false;
  } else {
    document.getElementById(dayOfTheWeek).classList.replace("badge-success", "badge-danger");
    document.getElementById(dayOfTheWeek).innerHTML = "Closed";
    document.getElementById(dayOfTheWeek + '_status').value = "0";
    document.getElementById(dayOfTheWeek + '1').readOnly = true;
    document.getElementById(dayOfTheWeek + '2').readOnly = true;
  }
}
// Function to change value of checkboxes when they are clicked
function copuloo_changeCheckboxValue(item)
{
  if (item.value == 0) { item.value = 1; }
  else { item.value = 0; }
}
