import moment from 'moment';

import avatar_generic from '../assets/img/avatar_generic.png';
import { server_to_client_instrument_map, client_to_server_instrument_map } from './globals.js';

// Instrument icon imports
import accordion24 from '../assets/img/instruments/icon_instrument_accordion24.png';
import acoustic_guitar24 from '../assets/img/instruments/icon_instrument_acoustic_guitar24.png';
import banjo24 from '../assets/img/instruments/icon_instrument_banjo24.png';
import bass_guitar24 from '../assets/img/instruments/icon_instrument_bass_guitar24.png';
import cello24 from '../assets/img/instruments/icon_instrument_cello24.png';
import clarinet24 from '../assets/img/instruments/icon_instrument_clarinet24.png';
import computer24 from '../assets/img/instruments/icon_instrument_computer24.png';
import default24 from '../assets/img/instruments/icon_instrument_default24.png';
import drums24 from '../assets/img/instruments/icon_instrument_drums24.png';
import electric_guitar24 from '../assets/img/instruments/icon_instrument_electric_guitar24.png';
import euphonium24 from '../assets/img/instruments/icon_instrument_euphonium24.png';
import flute24 from '../assets/img/instruments/icon_instrument_flute24.png';
import french_horn24 from '../assets/img/instruments/icon_instrument_french_horn24.png';
import harmonica24 from '../assets/img/instruments/icon_instrument_harmonica24.png';
import keyboard24 from '../assets/img/instruments/icon_instrument_keyboard24.png';
import mandolin24 from '../assets/img/instruments/icon_instrument_mandolin24.png';
import oboe24 from '../assets/img/instruments/icon_instrument_oboe24.png';
import other24 from '../assets/img/instruments/icon_instrument_other24.png';
import piano24 from '../assets/img/instruments/icon_instrument_piano24.png';
import saxophone24 from '../assets/img/instruments/icon_instrument_saxophone24.png';
import trombone24 from '../assets/img/instruments/icon_instrument_trombone24.png';
import trumpet24 from '../assets/img/instruments/icon_instrument_trumpet24.png';
import tuba24 from '../assets/img/instruments/icon_instrument_tuba24.png';
import ukulele24 from '../assets/img/instruments/icon_instrument_ukulele24.png';
import upright_bass24 from '../assets/img/instruments/icon_instrument_upright_bass24.png';
import double_bass24 from '../assets/img/instruments/icon_instrument_double_bass24.png';
import viola24 from '../assets/img/instruments/icon_instrument_viola24.png';
import violin24 from '../assets/img/instruments/icon_instrument_violin24.png';
import voice24 from '../assets/img/instruments/icon_instrument_voice24.png';

import accordion45 from '../assets/img/instruments/icon_instrument_accordion45.png';
import acoustic_guitar45 from '../assets/img/instruments/icon_instrument_acoustic_guitar45.png';
import banjo45 from '../assets/img/instruments/icon_instrument_banjo45.png';
import bass_guitar45 from '../assets/img/instruments/icon_instrument_bass_guitar45.png';
import cello45 from '../assets/img/instruments/icon_instrument_cello45.png';
import clarinet45 from '../assets/img/instruments/icon_instrument_clarinet45.png';
import computer45 from '../assets/img/instruments/icon_instrument_computer45.png';
import default45 from '../assets/img/instruments/icon_instrument_default45.png';
import drums45 from '../assets/img/instruments/icon_instrument_drums45.png';
import electric_guitar45 from '../assets/img/instruments/icon_instrument_electric_guitar45.png';
import euphonium45 from '../assets/img/instruments/icon_instrument_euphonium45.png';
import flute45 from '../assets/img/instruments/icon_instrument_flute45.png';
import french_horn45 from '../assets/img/instruments/icon_instrument_french_horn45.png';
import harmonica45 from '../assets/img/instruments/icon_instrument_harmonica45.png';
import keyboard45 from '../assets/img/instruments/icon_instrument_keyboard45.png';
import mandolin45 from '../assets/img/instruments/icon_instrument_mandolin45.png';
import oboe45 from '../assets/img/instruments/icon_instrument_oboe45.png';
import other45 from '../assets/img/instruments/icon_instrument_other45.png';
import piano45 from '../assets/img/instruments/icon_instrument_piano45.png';
import saxophone45 from '../assets/img/instruments/icon_instrument_saxophone45.png';
import trombone45 from '../assets/img/instruments/icon_instrument_trombone45.png';
import trumpet45 from '../assets/img/instruments/icon_instrument_trumpet45.png';
import tuba45 from '../assets/img/instruments/icon_instrument_tuba45.png';
import ukulele45 from '../assets/img/instruments/icon_instrument_ukulele45.png';
import upright_bass45 from '../assets/img/instruments/icon_instrument_upright_bass45.png';
import double_bass45 from '../assets/img/instruments/icon_instrument_double_bass45.png';
import viola45 from '../assets/img/instruments/icon_instrument_viola45.png';
import violin45 from '../assets/img/instruments/icon_instrument_violin45.png';
import voice45 from '../assets/img/instruments/icon_instrument_voice45.png';

import accordion45_inverted from '../assets/img/instruments/icon_instrument_accordion45_inverted.svg';
import acoustic_guitar45_inverted from '../assets/img/instruments/icon_instrument_acoustic_guitar45_inverted.svg';
import banjo45_inverted from '../assets/img/instruments/icon_instrument_banjo45_inverted.svg';
import bass_guitar45_inverted from '../assets/img/instruments/icon_instrument_bass_guitar45_inverted.svg';
import cello45_inverted from '../assets/img/instruments/icon_instrument_cello45_inverted.svg';
import clarinet45_inverted from '../assets/img/instruments/icon_instrument_clarinet45_inverted.svg';
import computer45_inverted from '../assets/img/instruments/icon_instrument_computer45_inverted.svg';
import default45_inverted from '../assets/img/instruments/icon_instrument_default45_inverted.svg';
import drums45_inverted from '../assets/img/instruments/icon_instrument_drums45_inverted.svg';
import electric_guitar45_inverted from '../assets/img/instruments/icon_instrument_electric_guitar45_inverted.svg';
import euphonium45_inverted from '../assets/img/instruments/icon_instrument_euphonium45_inverted.svg';
import flute45_inverted from '../assets/img/instruments/icon_instrument_flute45_inverted.svg';
import french_horn45_inverted from '../assets/img/instruments/icon_instrument_french_horn45_inverted.svg';
import harmonica45_inverted from '../assets/img/instruments/icon_instrument_harmonica45_inverted.svg';
import keyboard45_inverted from '../assets/img/instruments/icon_instrument_keyboard45_inverted.svg';
import mandolin45_inverted from '../assets/img/instruments/icon_instrument_mandolin45_inverted.svg';
import oboe45_inverted from '../assets/img/instruments/icon_instrument_oboe45_inverted.svg';
import other45_inverted from '../assets/img/instruments/icon_instrument_other45_inverted.svg';
import piano45_inverted from '../assets/img/instruments/icon_instrument_piano45_inverted.svg';
import saxophone45_inverted from '../assets/img/instruments/icon_instrument_saxophone45_inverted.svg';
import trombone45_inverted from '../assets/img/instruments/icon_instrument_trombone45_inverted.svg';
import trumpet45_inverted from '../assets/img/instruments/icon_instrument_trumpet45_inverted.svg';
import tuba45_inverted from '../assets/img/instruments/icon_instrument_tuba45_inverted.svg';
import ukulele45_inverted from '../assets/img/instruments/icon_instrument_ukelele45_inverted.svg';
import upright_bass45_inverted from '../assets/img/instruments/icon_instrument_upright_bass45_inverted.svg';
import double_bass45_inverted from '../assets/img/instruments/icon_instrument_double_bass45_inverted.svg';
import viola45_inverted from '../assets/img/instruments/icon_instrument_viola45_inverted.svg';
import violin45_inverted from '../assets/img/instruments/icon_instrument_violin45_inverted.svg';
import voice45_inverted from '../assets/img/instruments/icon_instrument_voice45_inverted.svg';

import accordion256 from '../assets/img/instruments/icon_instrument_accordion256.png';
import acoustic_guitar256 from '../assets/img/instruments/icon_instrument_acoustic_guitar256.png';
import banjo256 from '../assets/img/instruments/icon_instrument_banjo256.png';
import bass_guitar256 from '../assets/img/instruments/icon_instrument_bass_guitar256.png';
import cello256 from '../assets/img/instruments/icon_instrument_cello256.png';
import clarinet256 from '../assets/img/instruments/icon_instrument_clarinet256.png';
import computer256 from '../assets/img/instruments/icon_instrument_computer256.png';
import default256 from '../assets/img/instruments/icon_instrument_default256.png';
import drums256 from '../assets/img/instruments/icon_instrument_drums256.png';
import electric_guitar256 from '../assets/img/instruments/icon_instrument_electric_guitar256.png';
import euphonium256 from '../assets/img/instruments/icon_instrument_euphonium256.png';
import flute256 from '../assets/img/instruments/icon_instrument_flute256.png';
import french_horn256 from '../assets/img/instruments/icon_instrument_french_horn256.png';
import harmonica256 from '../assets/img/instruments/icon_instrument_harmonica256.png';
import keyboard256 from '../assets/img/instruments/icon_instrument_keyboard256.png';
import mandolin256 from '../assets/img/instruments/icon_instrument_mandolin256.png';
import oboe256 from '../assets/img/instruments/icon_instrument_oboe256.png';
import other256 from '../assets/img/instruments/icon_instrument_other256.png';
import piano256 from '../assets/img/instruments/icon_instrument_piano256.png';
import saxophone256 from '../assets/img/instruments/icon_instrument_saxophone256.png';
import trombone256 from '../assets/img/instruments/icon_instrument_trombone256.png';
import trumpet256 from '../assets/img/instruments/icon_instrument_trumpet256.png';
import tuba256 from '../assets/img/instruments/icon_instrument_tuba256.png';
import ukulele256 from '../assets/img/instruments/icon_instrument_ukulele256.png';
import upright_bass256 from '../assets/img/instruments/icon_instrument_upright_bass256.png';
import double_bass256 from '../assets/img/instruments/icon_instrument_double_bass256.png';
import viola256 from '../assets/img/instruments/icon_instrument_viola256.png';
import violin256 from '../assets/img/instruments/icon_instrument_violin256.png';
import voice256 from '../assets/img/instruments/icon_instrument_voice256.png';





export const isIterableArray = array => Array.isArray(array) && !!array.length;

//===============================
// Breakpoints
//===============================
export const breakpoints = {
  xs: 0,
  sm: 576,
  md: 768,
  lg: 992,
  xl: 1200,
  xxl: 1540
};

//===============================
// Store
//===============================
export const getItemFromStore = (key, defaultValue, store = localStorage) =>
  JSON.parse(store.getItem(key)) || defaultValue;
export const setItemToStore = (key, payload, store = localStorage) => store.setItem(key, JSON.stringify(payload));
export const getStoreSpace = (store = localStorage) =>
  parseFloat((escape(encodeURIComponent(JSON.stringify(store))).length / (1024 * 1024)).toFixed(2));

//===============================
// Cookie
//===============================
export const getCookieValue = name => {
  const value = document.cookie.match('(^|[^;]+)\\s*' + name + '\\s*=\\s*([^;]+)');
  return value ? value.pop() : null;
};

export const createCookie = (name, value, cookieExpireTime) => {
  const date = new Date();
  date.setTime(date.getTime() + cookieExpireTime);
  const expires = '; expires=' + date.toUTCString();
  document.cookie = name + '=' + value + expires + '; path=/';
};

//===============================
// Moment
//===============================
export const getDuration = (startDate, endDate) => {
  if (!moment.isMoment(startDate)) throw new Error(`Start date must be a moment object, received ${typeof startDate}`);
  if (endDate && !moment.isMoment(endDate))
    throw new Error(`End date must be a moment object, received ${typeof startDate}`);

  return `${startDate.format('ll')} - ${endDate ? endDate.format('ll') : 'Present'} • ${startDate.from(
    endDate || moment(),
    true
  )}`;
};

export const prettyPrintSeconds = (seconds) => {
  // from: http://stackoverflow.com/questions/3733227/javascript-seconds-to-minutes-and-seconds

  // Minutes and seconds
  var mins = ~~(seconds / 60);
  var secs = seconds % 60;

  // Hours, minutes and seconds
  var hrs = ~~(seconds / 3600);
  var mins = ~~((seconds % 3600) / 60);
  var secs = seconds % 60;

  // Output like "1:01" or "4:03:59" or "123:03:59"
  var ret = "";

  if (hrs > 0)
    ret += "" + hrs + ":" + (mins < 10 ? "0" : "");

  ret += "" + mins + ":" + (secs < 10 ? "0" : "");
  ret += "" + secs;
  return ret;
}

export const numberFormatter = (number, fixed = 2) => {
  // Nine Zeroes for Billions
  return Math.abs(Number(number)) >= 1.0e9
    ? (Math.abs(Number(number)) / 1.0e9).toFixed(fixed) + 'B'
    : // Six Zeroes for Millions
    Math.abs(Number(number)) >= 1.0e6
      ? (Math.abs(Number(number)) / 1.0e6).toFixed(fixed) + 'M'
      : // Three Zeroes for Thousands
      Math.abs(Number(number)) >= 1.0e3
        ? (Math.abs(Number(number)) / 1.0e3).toFixed(fixed) + 'K'
        : Math.abs(Number(number)).toFixed(fixed);
};

//===============================
// Colors
//===============================
export const hexToRgb = hexValue => {
  let hex;
  hexValue.indexOf('#') === 0 ? (hex = hexValue.substring(1)) : (hex = hexValue);
  // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
  const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(
    hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b)
  );
  return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : null;
};

export const rgbColor = (color = colors[0]) => `rgb(${hexToRgb(color)})`;
export const rgbaColor = (color = colors[0], alpha = 0.5) => `rgba(${hexToRgb(color)},${alpha})`;

export const colors = [
  '#2c7be5',
  '#00d97e',
  '#e63757',
  '#39afd1',
  '#fd7e14',
  '#02a8b5',
  '#727cf5',
  '#6b5eae',
  '#ff679b',
  '#f6c343'
];

export const themeColors = {
  primary: '#2c7be5',
  secondary: '#748194',
  success: '#00d27a',
  info: '#27bcfd',
  warning: '#f5803e',
  danger: '#e63757',
  light: '#f9fafd',
  dark: '#0b1727'
};

export const grays = {
  white: '#fff',
  100: '#f9fafd',
  200: '#edf2f9',
  300: '#d8e2ef',
  400: '#b6c1d2',
  500: '#9da9bb',
  600: '#748194',
  700: '#5e6e82',
  800: '#4d5969',
  900: '#344050',
  1000: '#232e3c',
  1100: '#0b1727',
  black: '#000'
};

export const darkGrays = {
  white: '#fff',
  1100: '#f9fafd',
  1000: '#edf2f9',
  900: '#d8e2ef',
  800: '#b6c1d2',
  700: '#9da9bb',
  600: '#748194',
  500: '#5e6e82',
  400: '#4d5969',
  300: '#344050',
  200: '#232e3c',
  100: '#0b1727',
  black: '#000'
};

export const getGrays = isDark => (isDark ? darkGrays : grays);

export const rgbColors = colors.map(color => rgbColor(color));
export const rgbaColors = colors.map(color => rgbaColor(color));

//===============================
// Echarts
//===============================
export const getPosition = (pos, params, dom, rect, size) => ({
  top: pos[1] - size.contentSize[1] - 10,
  left: pos[0] - size.contentSize[0] / 2
});

//===============================
// E-Commerce
//===============================
export const calculateSale = (base, less = 0, fix = 2) => (base - base * (less / 100)).toFixed(fix);
export const getTotalPrice = (cart, baseItems) =>
  cart.reduce((accumulator, currentValue) => {
    const { id, quantity } = currentValue;
    const { price, sale } = baseItems.find(item => item.id === id);
    return accumulator + calculateSale(price, sale) * quantity;
  }, 0);

//===============================
// Helpers
//===============================
export const getPaginationArray = (totalSize, sizePerPage) => {
  const noOfPages = Math.ceil(totalSize / sizePerPage);
  const array = [];
  let pageNo = 1;
  while (pageNo <= noOfPages) {
    array.push(pageNo);
    pageNo = pageNo + 1;
  }
  return array;
};

export const capitalize = str => (str.charAt(0).toUpperCase() + str.slice(1)).replace(/-/g, ' ');

export const titleize = (str) => {
  return str.replace(
    /\w\S*/g,
    (txt) => {
      return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    }
  );
}

export const truncate = (str, length = 100) => {
  if (!str) return;
  if (str.length <= length) {
    return str;
  } else {
    return `${str.substring(0, length)}...`;
  }
}

export const routesSlicer = ({ routes, columns = 3, rows }) => {
  const routesCollection = [];
  routes.map(route => {
    if (route.children) {
      return route.children.map(item => {
        if (item.children) {
          return routesCollection.push(...item.children);
        }
        return routesCollection.push(item);
      });
    }
    return routesCollection.push(route);
  });

  const totalRoutes = routesCollection.length;
  const calculatedRows = rows || Math.ceil(totalRoutes / columns);
  const routesChunks = [];
  for (let i = 0; i < totalRoutes; i += calculatedRows) {
    routesChunks.push(routesCollection.slice(i, i + calculatedRows));
  }
  return routesChunks;
};

export const getPageName = pageName => {
  return window.location.pathname.split('/').slice(-1)[0] === pageName;
};

export const copyToClipBoard = textFieldRef => {
  const textField = textFieldRef.current;
  textField.focus();
  textField.select();
  document.execCommand('copy');
};

export const currencyFormat = (num) => {
  return new Intl.NumberFormat('en-US',
    { style: 'currency', currency: 'USD' }
  ).format(num);
}

const days = new Array("Sun", "Mon", "Tue",
  "Wed", "Thu", "Fri", "Sat");

const months = new Array("January", "February", "March",
  "April", "May", "June", "July", "August", "September",
  "October", "November", "December");

export const monthName = (monthNumber) => {
  return months[monthNumber];
}

export const formatDateShort = (dateString) => {
  const date = dateString instanceof Date ? dateString : new Date(dateString);
  return months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
}

// returns Fri May 20, 2013
export const formatDate = (dateString, options = {}) => {
  if (!dateString) {
    return 'N/A'
  }

  const suppressDay = options.suppressDay || false;

  const date = new Date(dateString);
  return (suppressDay ? '' : (days[date.getDay()] + ' ')) + months[date.getMonth()] + ' ' + padString(date.getDate(), 2) + ', ' + date.getFullYear();
}

export const groupByKey = (list, key) => list.reduce((hash, obj) => ({ ...hash, [obj[key]]: (hash[obj[key]] || []).concat(obj) }), {})


const padString = (str, max) => {
  let retVal = '' + str;
  while (retVal.length < max) {
    retVal = '0' + retVal;
  }

  return retVal;
}

export const detectOS = () => {
  let platform;

  if (navigator.platform) {
    platform = navigator.platform.toLowerCase();
  } else if (navigator.userAgentData) {
    platform = navigator.userAgentData.platform.toLowerCase();
  }

  if (!platform) {
    return null;
  }

  if (platform.indexOf('mac') !== -1) {
    return "MacOSX";
  }
  if (platform.indexOf('win') !== -1) {
    return "Win32"
  }
  if (platform.indexOf('linux') !== -1) {
    return "Unix"
  }

  return null;
}

export const isAppleSilicon = () => {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl');

  // Best guess if the device is an Apple Silicon
  // https://stackoverflow.com/a/65412357
  // @ts-expect-error - Object is possibly 'null'
  return gl.getSupportedExtensions().indexOf('WEBGL_compressed_texture_etc') !== -1
}

export const formatUtcTime = (date, change) => {
  if (change) {
    date.setMinutes(Math.ceil(date.getMinutes() / 30) * 30);
  }
  var h12h = date.getHours();
  var m12h = date.getMinutes();
  var ampm;
  if (h12h >= 0 && h12h < 12) {
    if (h12h === 0) {
      h12h = 12; // 0 becomes 12
    }
    ampm = "AM";
  }
  else {
    if (h12h > 12) {
      h12h -= 12; // 13-23 becomes 1-11
    }
    ampm = "PM";
  }
  var timeString = ("00" + h12h).slice(-2) + ":" + ("00" + m12h).slice(-2) + " " + ampm;

  return timeString;
}

// http://stackoverflow.com/a/8809472/834644
export const generateUUID = function () {
  var d = new Date().getTime();
  var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
  });
  return uuid;
};

export const toQueryString = (obj, prefix) => {
  const str = [];
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      const k = prefix ? `${prefix}[${key}]` : key;
      const v = obj[key];
      if (typeof v === "object" && v !== null) {
        str.push(toQueryString(v, k));
      } else {
        str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
      }
    }
  }
  return str.join("&");
}

// Constants from gear_utils_async.js
export const ALERT_NAMES = {
  NO_EVENT: 0,
  BACKEND_ERROR: 1,
  BACKEND_MIXER_CHANGE: 2,
  PACKET_JTR: 3,
  PACKET_LOSS: 4,
  PACKET_LATE: 5,
  JTR_QUEUE_DEPTH: 6,
  NETWORK_JTR: 7,
  NETWORK_PING: 8,
  BITRATE_THROTTLE_WARN: 9,
  BANDWIDTH_LOW: 10,
  INPUT_IO_RATE: 11,
  INPUT_IO_JTR: 12,
  OUTPUT_IO_RATE: 13,
  OUTPUT_IO_JTR: 14,
  CPU_LOAD: 15,
  DECODE_VIOLATIONS: 16,
  LAST_THRESHOLD: 17,
  WIFI_NETWORK_ALERT: 18,
  NO_VALID_AUDIO_CONFIG: 19,
  AUDIO_DEVICE_NOT_PRESENT: 20,
  RECORD_PLAYBACK_STATE: 21,
  RUN_UPDATE_CHECK_BACKGROUND: 22,
  RUN_UPDATE_CHECK_INTERACTIVE: 23,
  STUN_EVENT: 24,
  DEAD_USER_WARN_EVENT: 25,
  DEAD_USER_REMOVE_EVENT: 26,
  WINDOW_CLOSE_BACKGROUND_MODE: 27,
  WINDOW_OPEN_FOREGROUND_MODE: 28,
  SESSION_LIVEBROADCAST_FAIL: 29,
  SESSION_LIVEBROADCAST_ACTIVE: 30,
  SESSION_LIVEBROADCAST_STOPPED: 31,
  SESSION_LIVEBROADCAST_PINNED: 32,
  SESSION_LIVEBROADCAST_UNPINNED: 33,
  BACKEND_STATUS_MSG: 34,
  LOCAL_NETWORK_VARIANCE_HIGH: 35,
  LOCAL_NETWORK_LATENCY_HIGH: 36,
  RECORDING_CLOSE: 37,
  PEER_REPORTS_NO_AUDIO_RECV: 38,
  SHOW_PREFERENCES: 39,
  USB_CONNECTED: 40,
  USB_DISCONNECTED: 41,
  JAM_TRACK_SERVER_ERROR: 42,
  BAD_INTERVAL_RATE: 43,
  FIRST_AUDIO_PACKET: 44,
  NETWORK_PORT_MANGLED: 45,
  NO_GLOBAL_CLOCK_SERVER: 46,
  GLOBAL_CLOCK_SYNCED: 47,
  RECORDING_DONE: 48,
  VIDEO_WINDOW_OPENED: 49,
  VIDEO_WINDOW_CLOSED: 50,
  VST_CHANGED: 51,
  SAMPLERATE_CONFIGURATION_BAD: 52,
  SHOW_NETWORK_TEST: 53,
  LAST_ALERT: 54
};

export const ASSIGNMENT = {
  CHAT: -2,
  OUTPUT: -1,
  UNASSIGNED: 0,
  TRACK1: 1,
  TRACK2: 2
};

export const VOICE_CHAT = {
  NO_CHAT: "0",
  CHAT: "1"
};

export const AUDIO_DEVICE_BEHAVIOR = {
  MacOSX_builtin: {
    display: 'MacOSX Built-In',
    shortName: 'Built-In',
    videoURL: "https://www.youtube.com/watch?v=7-9PW50ygHk",
    showKnobs: true,
    showASIO: false
  },
  MacOSX_interface: {
    display: 'MacOSX external interface',
    shortName: 'External',
    videoURL: "https://www.youtube.com/watch?v=7BLld6ogm14",
    showKnobs: true,
    showASIO: false
  },
  Win32_wdm: {
    display: 'Windows WDM',
    shortName: 'WDM',
    videoURL: "https://www.youtube.com/watch?v=L36UBkAV14c",
    showKnobs: true,
    showASIO: false
  },
  Win32_asio: {
    display: 'Windows ASIO',
    shortName: 'ASIO',
    videoURL: "https://www.youtube.com/watch?v=PGUmISTVVMY",
    showKnobs: true,
    showASIO: true
  },
  Win32_asio4all: {
    display: 'Windows ASIO4ALL',
    shortName: 'ASIO4ALL',
    videoURL: "https://www.youtube.com/watch?v=PGUmISTVVMY",
    showKnobs: true,
    showASIO: true
  },
  Linux: {
    display: 'Linux',
    shortName: 'linux',
    videoURL: undefined,
    showKnobs: true,
    showASIO: false
  }
};

export const EVENTS = {
  DIALOG_CLOSED: 'dialog_closed',
  SHOW_SIGNUP: 'show_signup',
  SHOW_SIGNIN: 'show_signin',
  RSVP_SUBMITTED: 'rsvp_submitted',
  RSVP_CANCELED: 'rsvp_canceled',
  USER_UPDATED: 'user_updated',
  SESSION_STARTED: 'session_started',
  SESSION_ENDED: 'session_stopped',
  FILE_MANAGER_CMD_START: 'file_manager_cmd_start',
  FILE_MANAGER_CMD_STOP: 'file_manager_cmd_stop',
  FILE_MANAGER_CMD_PROGRESS: 'file_manager_cmd_progress',
  FILE_MANAGER_CMD_ASAP_UPDATE: 'file_manager_cmd_asap_update',
  MIXER_MODE_CHANGED: 'mixer_mode_changed',
  MUTE_SELECTED: 'mute_selected',
  SUBSCRIBE_NOTIFICATION: 'subscribe_notification',
  CONNECTION_UP: 'connection_up',
  CONNECTION_DOWN: 'connection_down',
  SCREEN_CHANGED: 'screen_changed',
  JAMTRACK_DOWNLOADER_STATE_CHANGED: 'jamtrack_downloader_state',
  METRONOME_PLAYBACK_MODE_SELECTED: 'metronome_playback_mode_selected',
  CHECKOUT_SIGNED_IN: 'checkout_signed_in',
  CHECKOUT_SKIP_SIGN_IN: 'checkout_skip_sign_in',
  PREVIEW_PLAYED: 'preview_played',
  VST_OPERATION_SELECTED: 'vst_operation_selected',
  VST_EFFECT_SELECTED: 'vst_effect_selected',
  LESSON_SESSION_ACTION: 'lesson_session_action',
  JAMBLASTER_ACTION: 'jamblaster_action'
};

export const SYSTEM_DEFAULT_PLAYBACK_ONLY = 'System Default (Playback Only)';
export const JAMKAZAM_VIRTUAL_INPUT = "JamKazam Virtual Input";
export const SKIPPED_NETWORK_TEST = -1;


export const getAvatarUrl = (photo_url) => {
  return photo_url ? photo_url : avatar_generic;
};

// Instrument icon mappings
const icon_map_base = {
  "accordion": "accordion",
  "acoustic guitar": "acoustic_guitar",
  "banjo": "banjo",
  "bass guitar": "bass_guitar",
  "cello": "cello",
  "clarinet": "clarinet",
  "computer": "computer",
  "_default": "default",
  "drums": "drums",
  "percussion": "drums",
  "electric guitar": "electric_guitar",
  "euphonium": "euphonium",
  "flute": "flute",
  "french horn": "french_horn",
  "harmonica": "harmonica",
  "keyboard": "keyboard",
  "mandolin": "mandolin",
  "oboe": "oboe",
  "other": "other",
  "piano": "piano",
  "saxophone": "saxophone",
  "trombone": "trombone",
  "trumpet": "trumpet",
  "tuba": "tuba",
  "ukulele": "ukulele",
  "upright bass": "upright_bass",
  "double bass": "double_bass",
  "viola": "viola",
  "violin": "violin",
  "voice": "voice"
};

const instrumentIconMap24 = {
  "accordion": { asset: accordion24, name: "accordion" },
  "acoustic guitar": { asset: acoustic_guitar24, name: "acoustic guitar" },
  "banjo": { asset: banjo24, name: "banjo" },
  "bass guitar": { asset: bass_guitar24, name: "bass guitar" },
  "cello": { asset: cello24, name: "cello" },
  "clarinet": { asset: clarinet24, name: "clarinet" },
  "computer": { asset: computer24, name: "computer" },
  "_default": { asset: default24, name: "_default" },
  "drums": { asset: drums24, name: "drums" },
  "percussion": { asset: drums24, name: "percussion" },
  "electric guitar": { asset: electric_guitar24, name: "electric guitar" },
  "euphonium": { asset: euphonium24, name: "euphonium" },
  "flute": { asset: flute24, name: "flute" },
  "french horn": { asset: french_horn24, name: "french horn" },
  "harmonica": { asset: harmonica24, name: "harmonica" },
  "keyboard": { asset: keyboard24, name: "keyboard" },
  "mandolin": { asset: mandolin24, name: "mandolin" },
  "oboe": { asset: oboe24, name: "oboe" },
  "other": { asset: other24, name: "other" },
  "piano": { asset: piano24, name: "piano" },
  "saxophone": { asset: saxophone24, name: "saxophone" },
  "trombone": { asset: trombone24, name: "trombone" },
  "trumpet": { asset: trumpet24, name: "trumpet" },
  "tuba": { asset: tuba24, name: "tuba" },
  "ukulele": { asset: ukulele24, name: "ukulele" },
  "upright bass": { asset: upright_bass24, name: "upright bass" },
  "double bass": { asset: double_bass24, name: "double bass" },
  "viola": { asset: viola24, name: "viola" },
  "violin": { asset: violin24, name: "violin" },
  "voice": { asset: voice24, name: "voice" }
};

const instrumentIconMap45 = {
  "accordion": { asset: accordion45, name: "accordion" },
  "acoustic guitar": { asset: acoustic_guitar45, name: "acoustic guitar" },
  "banjo": { asset: banjo45, name: "banjo" },
  "bass guitar": { asset: bass_guitar45, name: "bass guitar" },
  "cello": { asset: cello45, name: "cello" },
  "clarinet": { asset: clarinet45, name: "clarinet" },
  "computer": { asset: computer45, name: "computer" },
  "_default": { asset: default45, name: "_default" },
  "drums": { asset: drums45, name: "drums" },
  "percussion": { asset: drums45, name: "percussion" },
  "electric guitar": { asset: electric_guitar45, name: "electric guitar" },
  "euphonium": { asset: euphonium45, name: "euphonium" },
  "flute": { asset: flute45, name: "flute" },
  "french horn": { asset: french_horn45, name: "french horn" },
  "harmonica": { asset: harmonica45, name: "harmonica" },
  "keyboard": { asset: keyboard45, name: "keyboard" },
  "mandolin": { asset: mandolin45, name: "mandolin" },
  "oboe": { asset: oboe45, name: "oboe" },
  "other": { asset: other45, name: "other" },
  "piano": { asset: piano45, name: "piano" },
  "saxophone": { asset: saxophone45, name: "saxophone" },
  "trombone": { asset: trombone45, name: "trombone" },
  "trumpet": { asset: trumpet45, name: "trumpet" },
  "tuba": { asset: tuba45, name: "tuba" },
  "ukulele": { asset: ukulele45, name: "ukulele" },
  "upright bass": { asset: upright_bass45, name: "upright bass" },
  "double bass": { asset: double_bass45, name: "double bass" },
  "viola": { asset: viola45, name: "viola" },
  "violin": { asset: violin45, name: "violin" },
  "voice": { asset: voice45, name: "voice" }
};

const instrumentIconMap45_inverted = {
  "accordion": { asset: accordion45_inverted, name: "accordion" },
  "acoustic guitar": { asset: acoustic_guitar45_inverted, name: "acoustic guitar" },
  "banjo": { asset: banjo45_inverted, name: "banjo" },
  "bass guitar": { asset: bass_guitar45_inverted, name: "bass guitar" },
  "cello": { asset: cello45_inverted, name: "cello" },
  "clarinet": { asset: clarinet45_inverted, name: "clarinet" },
  "computer": { asset: computer45_inverted, name: "computer" },
  "_default": { asset: default45_inverted, name: "_default" },
  "drums": { asset: drums45_inverted, name: "drums" },
  "percussion": { asset: drums45_inverted, name: "percussion" },
  "electric guitar": { asset: electric_guitar45_inverted, name: "electric guitar" },
  "euphonium": { asset: euphonium45_inverted, name: "euphonium" },
  "flute": { asset: flute45_inverted, name: "flute" },
  "french horn": { asset: french_horn45_inverted, name: "french horn" },
  "harmonica": { asset: harmonica45_inverted, name: "harmonica" },
  "keyboard": { asset: keyboard45_inverted, name: "keyboard" },
  "mandolin": { asset: mandolin45_inverted, name: "mandolin" },
  "oboe": { asset: oboe45_inverted, name: "oboe" },
  "other": { asset: other45_inverted, name: "other" },
  "piano": { asset: piano45_inverted, name: "piano" },
  "saxophone": { asset: saxophone45_inverted, name: "saxophone" },
  "trombone": { asset: trombone45_inverted, name: "trombone" },
  "trumpet": { asset: trumpet45_inverted, name: "trumpet" },
  "tuba": { asset: tuba45_inverted, name: "tuba" },
  "ukulele": { asset: ukulele45_inverted, name: "ukulele" },
  "upright bass": { asset: upright_bass45_inverted, name: "upright bass" },
  "double bass": { asset: double_bass45_inverted, name: "double bass" },
  "viola": { asset: viola45_inverted, name: "viola" },
  "violin": { asset: violin45_inverted, name: "violin" },
  "voice": { asset: voice45_inverted, name: "voice" }
};

const instrumentIconMap256 = {
  "accordion": { asset: accordion256, name: "accordion" },
  "acoustic guitar": { asset: acoustic_guitar256, name: "acoustic guitar" },
  "banjo": { asset: banjo256, name: "banjo" },
  "bass guitar": { asset: bass_guitar256, name: "bass guitar" },
  "cello": { asset: cello256, name: "cello" },
  "clarinet": { asset: clarinet256, name: "clarinet" },
  "computer": { asset: computer256, name: "computer" },
  "_default": { asset: default256, name: "_default" },
  "drums": { asset: drums256, name: "drums" },
  "percussion": { asset: drums256, name: "percussion" },
  "electric guitar": { asset: electric_guitar256, name: "electric guitar" },
  "euphonium": { asset: euphonium256, name: "euphonium" },
  "flute": { asset: flute256, name: "flute" },
  "french horn": { asset: french_horn256, name: "french horn" },
  "harmonica": { asset: harmonica256, name: "harmonica" },
  "keyboard": { asset: keyboard256, name: "keyboard" },
  "mandolin": { asset: mandolin256, name: "mandolin" },
  "oboe": { asset: oboe256, name: "oboe" },
  "other": { asset: other256, name: "other" },
  "piano": { asset: piano256, name: "piano" },
  "saxophone": { asset: saxophone256, name: "saxophone" },
  "trombone": { asset: trombone256, name: "trombone" },
  "trumpet": { asset: trumpet256, name: "trumpet" },
  "tuba": { asset: tuba256, name: "tuba" },
  "ukulele": { asset: ukulele256, name: "ukulele" },
  "upright bass": { asset: upright_bass256, name: "upright bass" },
  "double bass": { asset: double_bass256, name: "double bass" },
  "viola": { asset: viola256, name: "viola" },
  "violin": { asset: violin256, name: "violin" },
  "voice": { asset: voice256, name: "voice" }
};

const notSpecifiedText = "Not specified";

export const getInstrumentIconMap24 = () => {
  return instrumentIconMap24;
};

export const getInstrumentIconMap45 = () => {
  return instrumentIconMap45;
};

export const getInstrumentIconMap45_inverted = () => {
  return instrumentIconMap45_inverted;
};

export const getInstrumentIconMap256 = () => {
  return instrumentIconMap256;
};

export const getInstrumentIcon24 = (instrument) => {
  if (instrument in instrumentIconMap24) {
    return instrumentIconMap24[instrument].asset;
  }
  return instrumentIconMap24["_default"].asset;
};

export const getInstrumentIcon45 = (instrument) => {
  if (instrument in instrumentIconMap45) {
    return instrumentIconMap45[instrument].asset;
  }
  return instrumentIconMap45["_default"].asset;
};

export const getInstrumentIcon45_inverted = (instrument) => {
  if (instrument in instrumentIconMap45_inverted) {
    return instrumentIconMap45_inverted[instrument].asset;
  }
  return instrumentIconMap45_inverted["_default"].asset;
};

export const getInstrumentName = (instrument) => {
  if (instrument in instrumentIconMap45) {
    return instrumentIconMap45[instrument].name;
  }
  return instrumentIconMap45["_default"].name;
};

export const getInstrumentIcon256 = (instrument) => {
  if (instrument in instrumentIconMap256) {
    return instrumentIconMap256[instrument].asset;
  }
  return instrumentIconMap256["_default"].asset;
};

export const getInstrumentId = (instrumentId) => {
  return instrumentId ? instrumentId : notSpecifiedText;
};

// meant to pass in a bunch of images with an instrument-id attribute on them.
export const setInstrumentAssetPath = ($elements) => {
  // Adapted for React - assuming $elements is an array of elements
  $elements.forEach(element => {
    if (element.tagName === 'IMG') {
      const instrument = element.getAttribute('instrument-id');
      element.src = getInstrumentIcon24(instrument);
    }
  });
};

// creates an array with entries like [{ id: "drums", description: "Drums"}, ]
export const listInstruments = () => {
  const instrumentArray = [];
  Object.keys(server_to_client_instrument_map).forEach(key => {
    instrumentArray.push({ "id": server_to_client_instrument_map[key].client_id, "description": key });
  });
  return instrumentArray;
};

export const convertClientInstrumentToServer = (clientId) => {
  const serverInstrument = client_to_server_instrument_map[clientId];
  if (!serverInstrument) return 'other';
  else return serverInstrument.server_id;
};

export const dkeys = (d) => {
  var keys = []
  for (var i in d) {
    if (d.hasOwnProperty(i)) {
      keys.push(i);
    }
  }
  return keys;
};
