<?php 
session_start();
$valid = $_SESSION['_t'] && $_SESSION['_i'] && $_SESSION['_dt'] ? "true" : "false";
?>
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<title>Scanner</title>
    	<meta charset="utf-8">
    	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    	<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
		  <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
		  <link rel="stylesheet" href="https://unpkg.com/vue-qrcode-reader@2.0.1/dist/vue-qrcode-reader.css">
		  <script src="https://unpkg.com/vue-toasted"></script>
		  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
		  <script src="https://unpkg.com/vue-qrcode-reader@2.0.1/dist/vue-qrcode-reader.browser.js"></script>
		  <script
		  src="https://code.jquery.com/jquery-3.3.1.min.js"
		  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
		  crossorigin="anonymous"></script>

			<style lang="css">
				#app {
					background-color: black;
					position:relative;
				}
				@media only screen and (max-width: 600px){
					.toasted-container.bottom-right {
						right: 5%;
    				bottom: 7%;
					}
					.toasted-container {
			      min-width: inherit; 
					}
				}
			  .toasted {
			    color: white;
			    font-weight: bold;
			    padding: 3px 24px;
			    border-radius: 3px !important;
    			box-shadow: 1px 3px 5px -1px grey;
			  }
			  .toasted.success {
			    color: white;
			    font-weight: bold;
			  }
			  .toasted.error {
			    color: white;
			    font-weight: bold;
			  }
			  
				#scanner {
				  background-color: black;
				  position: fixed;
				  top:0;
				  width: 100vw;
				  height:100vh;
				  z-index:1;
				}
				.v-toolbar i {
				  text-shadow: 0px 0px 2px grey;
				}
				#video, #canvas {
				  top: 0;
				  left: 0;
				  padding: 0;
				  margin: 0;
				  position: absolute;
				  padding: 0;
				  border: 0;
				  object-fit: cover;
				}
				#video {
				  background: black;
				}
			  .primary {background-color: #c81933}
		    .error {background-color: #FF5252}
		    .info {background-color: #2196F3}
		    .success {background-color: #4CAF50}
		    .warning {background-color: #FFC107}

				.user-menu {
				  width: 100%;
				  left: 0px !important;
				}
			</style>
	</head>

	<body>
	<noscript>
		<div class="subheading">抱歉！你的瀏覽器已停用了JavaScript功能，請啟用JavaScript後重新整理頁面。</div>
	</noscript>
  <div id="app">
  	<v-app id="inspire" class="app">
			<div id='scanner'>
		    <video id="video"></video>
		    <canvas id="canvas" width="640" height="480" v-resize="initCanvas"></canvas>
		    <v-toolbar color="transparent" fixed flat dark height="40px" >
		      <v-btn flat icon @click="exitScanner">
		        <v-icon medium>chevron_left</v-icon>
		      </v-btn>
		      <v-spacer></v-spacer>
		      <v-btn flat icon :color="is_stop?'grey':'white'" @click="switchVideoMode">
		        <v-icon v-if="!is_stop">videocam</v-icon>
		        <v-icon v-else>videocam_off</v-icon>
		      </v-btn>
		      <v-btn flat icon :color="is_input_mode?'white':'grey'" @click="switchInputMode">
		        <v-icon>keyboard</v-icon>
		      </v-btn>
		      <v-menu v-model="is_input_mode" :close-on-content-click="false" content-class="user-menu" max-width="100%" offset-y origin="center center" :nudge-bottom="40" transition="slide-y-transition">
		        <v-toolbar card color="white">
		          <v-text-field
		            flat
		            solo
		            prepend-icon="create"
		            :placeholder="'Barcode / QRcode'"
		            v-model="inputCode"
		            @keypress.enter="searchCode"
		            type="search"
		            ref="search"
		            hide-details
		            autofocus
		          ></v-text-field>
		          <v-divider vertical inset></v-divider>
		          <v-btn icon flat @click="searchCode" class="ml-2" :class="{'ml-3':$vuetify.breakpoint.mdAndUp}">
		            <v-icon>search</v-icon>
		          </v-btn>         
		        </v-toolbar>
		      </v-menu>
		      <v-btn flat icon :color="is_mute?'grey':'white'" @click="switchSounds">
		        <v-icon v-if="!is_mute">volume_up</v-icon>
		        <v-icon v-else>volume_off</v-icon>
		      </v-btn>
		    </v-toolbar>
		  </div>
	  </v-app>
	</div>
		<!-- scanner -->
  	<script type="text/javascript" src="./js/zxing.min.js"></script>
		<!-- vue script -->
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
		<script>
	  	Vue.use(Toasted);
	  </script>
		<script>
			var app = new Vue({
			  el: '#app',
			  name: 'camera',
			  components: {
			  },
			  data: {
			  	is_init: false,
			  	is_input_mode: false,
			    is_mute: true,
			    is_stop: true,
			    inputCode: null,
			    codeReader: new ZXing.BrowserMultiFormatReader(),
			    deviceId: null,
			    enable_sounds: false,
			    correct_sound: new Audio('./sounds/correct.mp3'),
			    wrong_sound: new Audio('./sounds/wrong.mp3'),
			    last_scan: null,
			    is_prompted_permission_alert: false,
			    timeout: null,
			  },
			  mounted () {
			  	this.initScanner();
			  },
			  methods: {
			  	initCanvas() {
			  		$("#video,#canvas").css("width", "auto");
			  		$("#video,#canvas").css("height", "auto");
			  		let v = document.getElementById("video");
			  		let c = document.getElementById("canvas");
			  		c.width = v.offsetWidth;
			  		c.height = v.offsetHeight;
			  		// setTimeout(()=>{
				  		$("#video,#canvas").css("width", "100vw");
				  		$("#video,#canvas").css("height", "100vh");
				  	// }, 300);
			  	},
			    searchCode() {
			      this.last_scan = null;
			      this.handleQRCode(this.inputCode);
			    },
			    switchInputMode () {
			      this.stopScanner();
			      this.is_input_mode = !this.is_input_mode;
			      if (this.is_input_mode == true) {
			        setTimeout(()=>{
			          this.$refs.search.focus();
			        }, 300);
			      }
			    },
			    handleScan (text) {
			      if (this.last_scan!=text){
			        let _this = this;
			        this.last_scan = text;
			        if(text.includes('https://event.1ticks.com/HKHA?ref=')){
				    		var code = text.split('https://event.1ticks.com/HKHA?ref=')[1];
			    			this.handleQRCode(code);
			          if (this.timeout) { clearTimeout(this.timeout); }
			          this.timeout = setTimeout(()=>{
			            _this.last_scan = null;
			          }, 3000);
			        } else {
			          // unexpected code
			          this.handleWrongCode("format");
			          if (this.timeout) { clearTimeout(this.timeout); }
			          this.timeout = setTimeout(()=>{
			            _this.last_scan = null;
			          }, 3000);
			        }
			      }
			    },
			    handleQRCode (code) {
			      $.ajax({
			    		url: 'https://redirect.1ticks.com/redirect/public/api/sanrio_hkha/redeem', 
			    		data: {
								code: code
	          	},
	          	type: 'post',
    					dataType: 'json',
	          	headers: {
				        "x-1ticks-staff-token": "<?=$_SESSION['_t'];?>"
					    },
	          }).then((res) => {
			        if (!this.is_mute){
			          this.correct_sound.currentTime = 0;
			          this.correct_sound.play();
			        }
			        let ticket = res.data;
			        this.$toasted.show("簽到成功", {
			          theme: 'success',
			          type: 'info',
			          position: 'bottom-right',
			          icon: 'check',
			          duration: 8000
			        });
			        if (this.is_input_mode){
			          this.inputCode = "";
			          this.is_input_mode = false;
			          this.startScanner();
			        }
			      }).catch(err => {
			        console.dir(err);
			        this.handleWrongCode(err.status);
			      });
			    },
			    handleWrongCode (reason) {
			      if (!this.is_mute){
			        this.wrong_sound.currentTime = 0;
			        this.wrong_sound.play();
			      }
			      
			      switch (reason) {
			        case 'format':
			          this.$toasted.show("無效碼", {
			            theme: 'error',
			            type: 'error',
			            position: 'bottom-right',
			            icon: 'close',
			            duration: 5000
			          });
			          break;
			        case 403:
			          this.$toasted.show("入場碼已被使用", {
			            theme: 'error',
			            type: 'error',
			            position: 'bottom-right',
			            icon: 'close',
			            duration: 5000
			          });
			          break;
			        case 404:
			          this.$toasted.show("非此活動的有效入場碼", {
			            theme: 'error',
			            type: 'error',
			            position: 'bottom-right',
			            icon: 'close',
			            duration: 5000
			          });
			          break;
			        default:
			          console.error(reason);
			          this.showUnknownError(reason);
			          break;
			      }
			    },
			    initScanner() {
			      this.codeReader.getVideoInputDevices().then((videoInputDevices) => {
			        this.deviceId = videoInputDevices[0].deviceId;
			        this.startScanner();
			        // codeReader.reset()
			      }).catch((err) => {
			        swal("瀏覽器不支援", "The browser not supported", "error");
			        this.is_stop = true;
			      });
			    },
			    drawCanvas(points) {
			    	if (points.length >= 4) {
				    	let p1 = points[0]; // bottom-left
				    	let p2 = points[1]; // top-left
				    	let p3 = points[2];	// top-right
				    	let p4 = points[3]; // bottom-right

				    	let c = document.getElementById("canvas");
							let ctx = c.getContext("2d");
							ctx.strokeStyle = '#c81933';
							ctx.lineWidth = 3;

							ctx.clearRect(0, 0, c.width, c.height);
							ctx.beginPath();
							ctx.moveTo(p1.x-20, p1.y+20);
							ctx.lineTo(p2.x-20, p2.y-20);
							ctx.lineTo(p3.x+20, p3.y-20);
							// ctx.lineTo(p4.x+35, p4.y+38);
							ctx.lineTo(p1.x+p3.x-p2.x+18, p1.y+p3.y-p2.y+20);
							ctx.lineTo(p1.x-20, p1.y+20);
							ctx.closePath();
							ctx.stroke();
			    	} else if (points.length == 2) {
			    		let p1 = points[0]; // top-left
				    	let p2 = points[1]; // bottom-right

				    	let c = document.getElementById("canvas");
							let ctx = c.getContext("2d");
							ctx.strokeStyle = '#c81933';
							ctx.lineWidth = 3;

							ctx.clearRect(0, 0, c.width, c.height);
							ctx.beginPath();
							ctx.moveTo(p1.x-10, p1.y-30);
							ctx.lineTo(p2.x+10, p2.y-30);
							ctx.lineTo(p2.x+10, p2.y+30);
							ctx.lineTo(p1.x-10, p1.y+30);
							ctx.lineTo(p1.x-10, p1.y-30);
							ctx.closePath();
							ctx.stroke();
			    	}
			    },
			    startScanner() {
			      this.is_stop = false;
			      try {
			        this.codeReader.decodeFromInputVideoDeviceContinuously(this.deviceId, 'video', (result, err) => {
			        	if (!this.is_init) {
			        		this.is_init = true;
			  					this.initCanvas();
			        	}
			          if (!this.is_stop && result) {
			            // console.log(result);
			            this.handleScan(result.text);
			            console.log(result);
			            this.drawCanvas(result.resultPoints);
			          } else {
			          	let c = document.getElementById("canvas");
									let ctx = c.getContext("2d");
									ctx.clearRect(0, 0, c.width, c.height);
			          }
			          
			          if (err && !(err.name == "s" || err.name == "c")) {
			            console.dir(err);
			          }
			        }).catch(err => {
			        	console.dir(err);
			          if (err.code == 0 && !this.is_prompted_permission_alert) {
			            this.is_stop = true;
			            this.is_prompted_permission_alert = true;
			            swal("無法打開相機",'相機存取被拒','error');
			          } else {
			            this.is_stop = true;
			            this.$toasted.show("相機存取被拒", {
			              theme: 'error',
			              type: 'error',
			              position: 'bottom-right',
			              icon: 'block',
			              duration: 3000
			            });
			            if (!this.is_mute){
			              this.wrong_sound.currentTime = 0;
			              this.wrong_sound.play();
			            }
			          }
			        });
			      } catch (err) {
			        console.dir(err);
			      }
			    },
			    stopScanner() {
			      this.is_stop = true;
			      this.last_scan = null;
			      this.codeReader.stopStreams();
			      let c = document.getElementById("canvas");
						let ctx = c.getContext("2d");
						ctx.clearRect(0, 0, c.width, c.height);
			    },
			    exitScanner() {
			      this.stopScanner();
			      location.assign('./index.php');
			    },
			    switchSounds() {
			      if (!this.enable_sounds) {
			        this.enable_sounds = true;
			        this.correct_sound.play();
			        this.correct_sound.pause();

			        this.wrong_sound.play();
			        this.wrong_sound.pause();
			      }
			      this.is_mute = !this.is_mute;
			    },
			    switchVideoMode() {
			      if (this.is_stop) {
			        this.is_input_mode = false;
			        this.startScanner();
			      } else {
			        this.stopScanner();
			      }
			    },
			  }
			});
		</script>
	</body>
</html>
