/**
 * @file browser.js
 * @module browser
 */
import * as Dom from './dom' ;
import window from 'global/window' ;

const USER_AGENT = window.navigator && window.navigator.userAgent || '' ;
const webkitVersionMap = (/AppleWebKit\/([\d.]+)/i).exec(USER_AGENT) ;
const appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null ;

/**
 * Si l'appareil est un iPod ou non.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_IPOD = (/iPod/i).test(USER_AGENT) ;

/**
 * La version d'iOS détectée - ou `null`.
 *
 * @statique
 * @const
 * @type {string|null}
 */
export const IOS_VERSION = (function() {
  const match = USER_AGENT.match(/OS (\d+)_/i) ;

  if (match && match[1]) {
    return match[1] ;
  }
  retourner null ;
}()) ;

/**
 * Qu'il s'agisse ou non d'un appareil Android.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_ANDROID = (/Android/i).test(USER_AGENT) ;

/**
 * La version d'Android détectée - ou `null`.
 *
 * @statique
 * @const
 * @type {nombre|chaîne|nul}
 */
export const ANDROID_VERSION = (function() {
  // Cela correspond aux versions majeures, mineures et correctives d'Android
  // ANDROID_VERSION est Major.Minor sous la forme d'un nombre, si Minor n'est pas disponible, seul Major est renvoyé
  const match = USER_AGENT.match(/Android (\d+)(?:\d.(\d+)) ?(?:\d.(\d+))*/i) ;

  if (!match) {
    retourner null ;
  }

  const major = match[1] && parseFloat(match[1]) ;
  const minor = match[2] && parseFloat(match[2]) ;

  if (major && minor) {
    return parseFloat(match[1] + '.' + match[2]) ;
  else if (major) {
    retour majeur ;
  }
  retourner null ;
}()) ;

/**
 * Il s'agit ou non d'un navigateur Android natif.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537 ;

/**
 * S'il s'agit ou non de Mozilla Firefox.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_FIREFOX = (/Firefox/i).test(USER_AGENT) ;

/**
 * Qu'il s'agisse ou non de Microsoft Edge.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_EDGE = (/Edg/i).test(USER_AGENT) ;

/**
 * Qu'il s'agisse ou non de Google Chrome.
 *
 * Ce sera également `vrai` pour Chrome sur iOS, qui aura un support différent
 * car il s'agit en fait de Safari sous le capot.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_CHROME = !IS_EDGE && ((/Chrome/i).test(USER_AGENT) || (/CriOS/i).test(USER_AGENT)) ;

/**
 * La version de Google Chrome détectée - ou `null`.
 *
 * @statique
 * @const
 * @type {nombre|null}
 */
export const CHROME_VERSION = (function() {
  const match = USER_AGENT.match(/(Chrome|CriOS)\/(\d+)/) ;

  if (match && match[2]) {
    return parseFloat(match[2]) ;
  }
  retourner null ;
}()) ;

/**
 * La version d'Internet Explorer détectée - ou `null`.
 *
 * @statique
 * @const
 * @type {nombre|null}
 */
export const IE_VERSION = (function() {
  const result = (/MSIE\s(\d+)\d.\d/).exec(USER_AGENT) ;
  let version = result && parseFloat(result[1]) ;

  if (!version && (/Trident\/7.0/i).test(USER_AGENT) && (/rv:11.0/).test(USER_AGENT))) {
    // IE 11 a une chaîne d'agent utilisateur différente de celle des autres versions d'IE
    version = 11.0 ;
  }

  version de retour ;
}()) ;

/**
 * Qu'il s'agisse ou non d'un Safari de bureau.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_SAFARI = (/Safari/i).test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE ;

/**
 * S'il s'agit d'une machine Windows ou non.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_WINDOWS = (/Windows/i).test(USER_AGENT) ;

/**
 * Indique si l'appareil est tactile ou non.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const TOUCH_ENABLED = Boolean(Dom.isReal() && (
  'ontouchstart' dans la fenêtre ||
  window.navigator.maxTouchPoints ||
  window.DocumentTouch && window.document instanceof window.DocumentTouch)) ;

/**
 * Qu'il s'agisse ou non d'un iPad.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_IPAD = (/iPad/i).test(USER_AGENT) ||
  (IS_SAFARI && TOUCH_ENABLED && !(/iPhone/i).test(USER_AGENT)) ;

/**
 * Qu'il s'agisse ou non d'un iPhone.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
// L'UIWebView de l'application Facebook s'identifie à la fois comme un iPhone et un iPad, donc
// pour identifier les iPhones, il faut exclure les iPads.
// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
export const IS_IPHONE = (/iPhone/i).test(USER_AGENT) && !IS_IPAD ;

/**
 * S'il s'agit ou non d'un appareil iOS.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD ;

/**
 * Qu'il s'agisse ou non de n'importe quelle version de Safari - y compris iOS.
 *
 * @statique
 * @const
 * @type {Booléen}
 */
export const IS_ANY_SAFARI = (IS_SAFARI || IS_IOS) && !IS_CHROME ;