text: // import { Constants, Camera, FileSystem, Permissions } from "expo";
  import React from 'react';
  import { StyleSheet, Text, View, TouchableOpacity, Slider, Vibration } from 'react-native';
  import { Camera } from 'expo-camera';
  import { FileSystem } from 'expo-file-system';
  import { Permissions } from 'expo-permissions';
  import isIPhoneX from 'react-native-is-iphonex';
  
  import GalleryScreen from './GalleryScreen';
  
  // If you remove native Face Detector dependency,
  // accessing `FaceDetector.Mode` will result in failure (as there is no native module)
  // and importing `expo-face-detector` does try to access FaceDetector.Mode.
  const shouldIncludeFaceDetector = true;
  const FaceDetectorModule = shouldIncludeFaceDetector
    ? require('expo-face-detector')
    : { FaceDetector: {} };
  const { FaceDetector } = FaceDetectorModule;
  
  const Constants = { statusBarHeight: 20 };
  
  const landmarkSize = 2;
  
  const flashModeOrder = {
    off: 'on',
    on: 'auto',
    auto: 'torch',
    torch: 'off',
  };
  
  const wbOrder = {
    auto: 'sunny',
    sunny: 'cloudy',
    cloudy: 'shadow',
    shadow: 'fluorescent',
    fluorescent: 'incandescent',
    incandescent: 'auto',
  };
  
  export default class CameraScreen extends React.Component {
    state = {
      flash: 'off',
      zoom: 0,
      autoFocus: 'on',
      depth: 0,
      type: 'back',
      whiteBalance: 'auto',
      ratio: '16:9',
      ratios: [],
      photoId: 1,
      showGallery: false,
      photos: [],
      faces: [],
      permissionsGranted: false,
    };
  
    async componentWillMount() {
      const { status } = await Permissions.askAsync(Permissions.CAMERA);
      // this.setState({ permissionsGranted: status === 'granted' });
    }
  
    componentDidCatch(error) {
      console.warn(error);
    }
  
    componentDidMount() {
      FileSystem.makeDirectoryAsync(FileSystem.documentDirectory + 'photos').catch(e => {
        console.log(e, 'Directory exists');
      });
    }
  
    getRatios = async () => {
      const ratios = await this.camera.getSupportedRatios();
      return ratios;
    };
  
    toggleView() {
      this.setState({
        showGallery: !this.state.showGallery,
      });
    }
  
    toggleFacing() {
      this.setState({
        type: this.state.type === 'back' ? 'front' : 'back',
      });
    }
  
    toggleFlash() {
      this.setState({
        flash: flashModeOrder[this.state.flash],
      });
    }
  
    setRatio(ratio) {
      this.setState({
        ratio,
      });
    }
  
    toggleWB() {
      this.setState({
        whiteBalance: wbOrder[this.state.whiteBalance],
      });
    }
  
    toggleFocus() {
      this.setState({
        autoFocus: this.state.autoFocus === 'on' ? 'off' : 'on',
      });
    }
  
    zoomOut() {
      this.setState({
        zoom: this.state.zoom - 0.1 < 0 ? 0 : this.state.zoom - 0.1,
      });
    }
  
    zoomIn() {
      this.setState({
        zoom: this.state.zoom + 0.1 > 1 ? 1 : this.state.zoom + 0.1,
      });
    }
  
    setFocusDepth(depth) {
      this.setState({
        depth,
      });
    }
  
    takePicture = () => {
      if (this.camera) {
        this.camera
          .takePictureAsync()
          .then(data => {
            FileSystem.moveAsync({
              from: data.uri,
              to: `${FileSystem.documentDirectory}photos/Photo_${this.state.photoId}.jpg`,
            })
              .then(() => {
                this.setState({ photoId: this.state.photoId + 1 });
                Vibration.vibrate();
              })
              .catch(error => console.warn('takePicture', error));
          })
          .catch(error => console.warn('takePicture', error));
      }
    };
  
    onFacesDetected = ({ faces }) => this.setState({ faces });
    onFaceDetectionError = state => console.warn('Faces detection error:', state);
  
    renderFace({ bounds, faceID, rollAngle, yawAngle }) {
      return (
        <View
          key={faceID}
          transform={[
            { perspective: 600 },
            { rotateZ: `${rollAngle.toFixed(0)}deg` },
            { rotateY: `${yawAngle.toFixed(0)}deg` },
          ]}
          style={[
            styles.face,
            {
              ...bounds.size,
              left: bounds.origin.x,
              top: bounds.origin.y,
            },
          ]}>
          <Text style={styles.faceText}>ID: {faceID}</Text>
          <Text style={styles.faceText}>rollAngle: {rollAngle.toFixed(0)}</Text>
          <Text style={styles.faceText}>yawAngle: {yawAngle.toFixed(0)}</Text>
        </View>
      );
    }
  
    renderLandmarksOfFace(face) {
      const renderLandmark = position =>
        position && (
          <View
            style={[
              styles.landmark,
              {
                left: position.x - landmarkSize / 2,
                top: position.y - landmarkSize / 2,
              },
            ]}
          />
        );
      return (
        <View key={`landmarks-${face.faceID}`}>
          {renderLandmark(face.leftEyePosition)}
          {renderLandmark(face.rightEyePosition)}
          {renderLandmark(face.leftEarPosition)}
          {renderLandmark(face.rightEarPosition)}
          {renderLandmark(face.leftCheekPosition)}
          {renderLandmark(face.rightCheekPosition)}
          {renderLandmark(face.leftMouthPosition)}
          {renderLandmark(face.mouthPosition)}
          {renderLandmark(face.rightMouthPosition)}
          {renderLandmark(face.noseBasePosition)}
          {renderLandmark(face.bottomMouthPosition)}
        </View>
      );
    }
  
    renderFaces() {
      return (
        <View style={styles.facesContainer} pointerEvents="none">
          {this.state.faces.map(this.renderFace)}
        </View>
      );
    }
  
    renderLandmarks() {
      return (
        <View style={styles.facesContainer} pointerEvents="none">
          {this.state.faces.map(this.renderLandmarksOfFace)}
        </View>
      );
    }
  
    renderNoPermissions() {
      return (
        <View
          style={{
            flex: 1,
            alignItems: 'center',
            justifyContent: 'center',
            padding: 10,
          }}>
          <TouchableOpacity onPress={() => this.setState({ permissionsGranted: true })}>
            <Text style={{ color: 'white' }}>
              Camera permissions not granted - cannot open camera preview.
            </Text>
          </TouchableOpacity>
        </View>
      );
    }
  
    renderGallery() {
      return <GalleryScreen onPress={this.toggleView.bind(this)} />;
    }
  
    renderGalleryButton() {
      return (
        <TouchableOpacity
          style={[styles.flipButton, styles.galleryButton, { flex: 0.25, alignSelf: 'flex-end' }]}
          onPress={this.toggleView.bind(this)}>
          <Text style={styles.flipText}> Gallery </Text>
        </TouchableOpacity>
      );
    }
  
    renderCamera() {
      const faceDetectorSettings = shouldIncludeFaceDetector
        ? {
            tracking: true,
            mode: FaceDetector.Constants.Mode.fast,
            detectLandmarks: FaceDetector.Constants.Landmarks.all,
            runClassifications: FaceDetector.Constants.Classifications.all,
          }
        : null;
      // return <Camera style={{ flex: 1 }} onCameraReady={() => console.error('camera rady!')} />;
      return (
        <Camera
          ref={ref => {
            this.camera = ref;
          }}
          style={{ flex: 1 }}
          type={this.state.type}
          flashMode={this.state.flash}
          autoFocus={this.state.autoFocus}
          zoom={this.state.zoom}
          whiteBalance={this.state.whiteBalance}
          ratio={this.state.ratio}
          faceDetectorSettings={faceDetectorSettings}
          onFacesDetected={this.onFacesDetected}
          onFaceDetectionError={this.onFaceDetectionError}
          focusDepth={this.state.depth}>
          <View
            style={{
              flex: 0.5,
              backgroundColor: 'transparent',
              flexDirection: 'row',
              justifyContent: 'space-around',
              paddingTop: Constants.statusBarHeight / 2,
            }}>
            <TouchableOpacity style={styles.flipButton} onPress={this.toggleFacing.bind(this)}>
              <Text style={styles.flipText}> FLIP </Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.flipButton} onPress={this.toggleFlash.bind(this)}>
              <Text style={styles.flipText}> FLASH: {this.state.flash} </Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.flipButton} onPress={this.toggleWB.bind(this)}>
              <Text style={styles.flipText}> WB: {this.state.whiteBalance} </Text>
            </TouchableOpacity>
          </View>
          <View
            style={{
              flex: 0.4,
              backgroundColor: 'transparent',
              flexDirection: 'row',
              alignSelf: 'flex-end',
              marginBottom: -5,
            }}>
            {this.state.autoFocus !== 'on' ? (
              <Slider
                style={{ width: 150, marginTop: 15, marginRight: 15, alignSelf: 'flex-end' }}
                onValueChange={this.setFocusDepth.bind(this)}
                step={0.1}
              />
            ) : null}
          </View>
          <View
            style={{
              flex: 0.1,
              paddingBottom: isIPhoneX ? 20 : 0,
              backgroundColor: 'transparent',
              flexDirection: 'row',
              alignSelf: 'stretch',
            }}>
            <TouchableOpacity
              style={[styles.flipButton, { flex: 0.1, alignSelf: 'flex-end' }]}
              onPress={this.zoomIn.bind(this)}>
              <Text style={styles.flipText}> + </Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={[styles.flipButton, { flex: 0.1, alignSelf: 'flex-end' }]}
              onPress={this.zoomOut.bind(this)}>
              <Text style={styles.flipText}> - </Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={[styles.flipButton, { flex: 0.25, alignSelf: 'flex-end' }]}
              onPress={this.toggleFocus.bind(this)}>
              <Text style={styles.flipText}> AF : {this.state.autoFocus} </Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={[styles.flipButton, styles.picButton, { flex: 0.3, alignSelf: 'flex-end' }]}
              onPress={this.takePicture}>
              <Text style={styles.flipText}> SNAP </Text>
            </TouchableOpacity>
            {this.renderGalleryButton()}
          </View>
          {this.renderFaces()}
          {this.renderLandmarks()}
        </Camera>
      );
    }
  
    render() {
      const cameraScreenContent = this.state.permissionsGranted
        ? this.renderCamera()
        : this.renderNoPermissions();
      const content = this.state.showGallery ? this.renderGallery() : cameraScreenContent;
      return <View style={styles.container}>{content}</View>;
    }
  }
  
  const styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: '#000',
    },
    navigation: {
      flex: 1,
    },
    gallery: {
      flex: 1,
      flexDirection: 'row',
      flexWrap: 'wrap',
    },
    flipButton: {
      flex: 0.3,
      height: 40,
      marginHorizontal: 2,
      marginBottom: 10,
      marginTop: 20,
      borderRadius: 8,
      borderColor: 'white',
      borderWidth: 1,
      padding: 5,
      alignItems: 'center',
      justifyContent: 'center',
    },
    flipText: {
      color: 'white',
      fontSize: 15,
    },
    item: {
      margin: 4,
      backgroundColor: 'indianred',
      height: 35,
      width: 80,
      borderRadius: 5,
      alignItems: 'center',
      justifyContent: 'center',
    },
    picButton: {
      backgroundColor: 'darkseagreen',
    },
    galleryButton: {
      backgroundColor: 'indianred',
    },
    facesContainer: {
      position: 'absolute',
      bottom: 0,
      right: 0,
      left: 0,
      top: 0,
    },
    face: {
      padding: 10,
      borderWidth: 2,
      borderRadius: 2,
      position: 'absolute',
      borderColor: '#FFD700',
      justifyContent: 'center',
      backgroundColor: 'rgba(0, 0, 0, 0.5)',
    },
    landmark: {
      width: landmarkSize,
      height: landmarkSize,
      position: 'absolute',
      backgroundColor: 'red',
    },
    faceText: {
      color: '#FFD700',
      fontWeight: 'bold',
      textAlign: 'center',
      margin: 10,
      backgroundColor: 'transparent',
    },
    row: {
      flexDirection: 'row',
    },
  });
  