<!--

 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.

-->

<!DOCTYPE html>

<!--

	This sample index.html is a "bare bones" example of using web development
	to produce a webOS app using mini Mojo. This is *not* designed to illustrate
	best practices (as the advanced developer will notice right off), but
	rather to show that even basic "web 1.0" skills can successfully create an
	app.

-->


<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>cordova WebOS</title>
	
	<script type="text/javascript" src="cordova-1.8.1.js"></script>   
	<script type="text/javascript">
		// create global var for sqlite database instance
		var db;
	</script>
		
	<link rel="stylesheet" type="text/css" href="menu.css">
	
</head>
<body>

<div id="menu">
	<a onclick="page('screen');">Adjust Screen Settings</a>
	<a onclick="page('notifications');">Notification Examples</a>
	<a onclick="info();">Show Device Info</a>
	<a onclick="page('net');">Show Network Info</a>		
	<a onclick="window.debug.log('trace this');">Console Logging</a>
	<a onclick="launchmap()">Launch Map App</a>
	<a onclick="navigator.window.newCard('dashboard.html'); menu(false);">Launch New Card</a>
	<a onclick="getPicture();">Launch Camera</a>
	<a onclick="storage();">Storage Tests</a> 
	<a onclick="callCordovaExec();menu(false);">cordova Exec</a>
	<a onclick="page('touchDemo');">Touch Events Examples</a>
	<a onclick="page('compassDemo');">Compass API</a>
	<a onclick="menu(false);">Done</a>
</div>

<div id="screen">
	<p><input type="checkbox" onchange="navigator.window.setFullScreen(this.checked);">navigator.window.setFullScreen();</p>
	<p><input type="checkbox" onchange="navigator.window.blockScreenTimeout(this.checked);">navigator.window.blockScreenTimeout();</p>
	<p><input type="checkbox" onchange="navigator.accelerometer.setFastAccelerometer(this.checked);">navigator.accelerometer.fastAccelerometer();</p>
	
	<p>navigator.orientation.setWindowOrientation();</p>
	<input type="radio" onchange="navigator.orientation.setOrientation(this.value);" value="up" name="orientation" checked>up
	<input type="radio" onchange="navigator.orientation.setOrientation(this.value);" value="down" name="orientation">down
	<input type="radio" onchange="navigator.orientation.setOrientation(this.value);" value="left" name="orientation">left
	<input type="radio" onchange="navigator.orientation.setOrientation(this.value);" value="right" name="orientation">right
	<input type="radio" onchange="navigator.orientation.setOrientation(this.value);" value="free" name="orientation">free
		
	<p>navigator.orientation.getCurrentOrientation()</p>
	<button onclick="displayCurrentOrientation();">Get Current Orientation</button>  	
</div>

<div id="notifications" style="display: none;">
	<p>navigator.notification.newDashboard();</p>
	<button onclick="navigator.notification.newDashboard('dashboard.html');">Dashboard</button>
	
	<p>navigator.notification.alert();</p>
	<button onclick="navigator.notification.alert('alert');">Show Alert</button>
	
	<p>navigator.notification.showBanner();</p>
	<button onclick="navigator.notification.showBanner('Banner test','banner');">Show Banner Message</button>	
</div>

<div id="blank" width="100%" height="100%" style="background: #FFFFFF;"></div>

<div id="info" style="display: none;"></div>

<div id="net" style="display: none;">
    <p>navigator.network.isReachable</p>
    <button id="isReachable" onclick="isReachable();">isReachable</button>
    <p>navigator.network.connection</p>
    <button id="connection" onclick="networkConnection();">connection</button>
    <p>navigator.network.connection.type</p>
    <button id="connectionType" onclick="networkConnectionType();">connection type</button>
    <div id="networkResult"></div>
    
</div>

<div id="camera" style="display: none;"></div>

<div id="touchDemo" style="display: none;">
	<p>Touch Events Demo</p>
	<button id="btnTouchStart">Touch Start</button>
	<button id="btnTouchEnd">Touch End</button>
	<p>Run your finger/mouse along button to trigger touchmove</p>
	<button id="btnTouchMove" width="250">Touch Move</button>	
	<p>Mouse Events Demo</p>
	<button id="btnMouseDown">Mouse Down</button>
	<button id="btnMouseUp">Mouse Up</button>
	<p>Run your finger/mouse along button to trigger mousemove</p>
	<button id="btnMouseMove" width="250">Mouse Move</button>
</div> 

<div id="storage" style="display: none">
	<p>storage tests</p>
	<button onclick="createDB();">Test SQLite DB</button> 
	<div id="storageResults"></div>
</div>

<div id="compassDemo" style="display: none;">
    <p>Compass Demo</p>
	<button id="btnGetCurrentHeading" onclick="displayCurrentHeading();">Get Current Heading</button>    
    <p>Watch Heading</p>
    <button id="btnStartCompassWatch" onclick="startCompassWatch();">Start Compass Watch</button>
    <button id="btnStopCompassWatch" onclick="stopCompassWatch();">Stop Compass Watch</button>
    <div id="compassResult"></div>

</div>

<script>                         
document.addEventListener('deviceready', function () {
    // cordova is ready, do all your stuf here
}, false);

var watchId = null;

function displayCurrentHeading() {
    
    function successful(response) {
        //navigator.notification.alert("last heading: " + JSON.stringify(response));
        var compassPage = document.getElementById("compassResult");
        compassPage.innerHTML = "current heading: "
        compassPage.innerHTML += JSON.stringify(response);
    }
    
    var request = navigator.compass.getCurrentHeading(successful, {});
    
}

function startCompassWatch() {
    // set frequency of compass updates in milliseconds
    var options = { frequency: 5000 };
    
    function onStartCompassSuccess(heading) {
        navigator.notification.alert("Heading: " + heading);
    }
    
    watchId = navigator.compass.watchHeading(onStartCompassSuccess, onCompassError, options);
}

function stopCompassWatch() {
    if (watchId) {
        navigator.compass.clearWatch(watchId);
        watchId = null;
    }
}

function onCompassError(compassError) {
    navigator.notification.alert("Compass error");// + compassError.code);
}


// setup event listeners for touch events 
document.querySelector('#btnTouchStart').addEventListener('touchstart', onTouchEvent, false);
document.querySelector('#btnTouchEnd').addEventListener('touchend', onTouchEvent, false);
document.querySelector('#btnTouchMove').addEventListener('touchmove', onTouchEvent, false);
// setup event listeners for mouse events
document.querySelector('#btnMouseDown').addEventListener('mousedown', onTouchEvent, false);
document.querySelector('#btnMouseUp').addEventListener('mouseup', onTouchEvent, false);
document.querySelector('#btnMouseMove').addEventListener('mousemove', onTouchEvent, false);

function onTouchEvent(event) {
	navigator.notification.alert(event.type);
}

function callCordovaExec() {
    
    navigator.notification.alert(Cordova.ready);
    
	//win, fail, clazz, action, args
	Cordova.exec(success, fail, 'navigator.notification', 'alert', 'testing exec'); 
	
	function success(msg) {
		console.log(msg + ' exec succeeded');
	}
	
	function fail(msg) {
		//navigator.notification.alert('exec failed');
		console.log(msg + ' exec failed');
	}
}

function createDB() {  
	document.getElementById('storageResults').innerHTML = '';
	db = window.openDatabase("test", "1.0", "Test DB", false);
	db.transaction(populateDB, errorCB, successCB);
}

function populateDB(tx) {
	tx.executeSql('DROP TABLE IF EXISTS DEMO');
	tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)');
	tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")');
	tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")');
}

function errorCB(tx, err) {
	navigator.notification.alert("error: " + err);
}

function successCB() {
	navigator.notification.alert('successfully created & populated');  
	db.transaction(queryDB, errorCB);
}

function queryDB(tx) {
	tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);
}

function querySuccess(tx, results) {     
	var len = results.rows.length;
	navigator.notification.alert('rows inserted: ' + len);
	
	if (len > 0) {
		for (var i=0;i<len;i++) {
			navigator.notification.alert('id: ' + results.rows.item(i).id + ' data: ' + results.rows.item(i).data);
		}
	}
}

function info() {
	var deviceinfo = JSON.stringify(navigator.device.getDeviceInfo()).replace(/,/g, ', ');
	page('info');
	lastpage.innerHTML = deviceinfo;
}
              
function storage() {
	page('storage');
}

function isReachable() {
	var netpage = document.getElementById("networkResult");
	netpage.innerHTML = "Requesting network info...";
	
	function successful(response) {
		
		var states = {};
		        states[NetworkStatus.NOT_REACHABLE]                      = 'No network connection';
		        states[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
		        states[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK]         = 'WiFi connection';
		
		
		var r = JSON.stringify(states[response]);
		netpage.innerHTML = r.replace(/,/g, ', ');
		netpage.innerHTML += response.toString();
	}
	
	var request = navigator.network.isReachable('palm://com.palm.connectionmanager', successful, {});
}

function networkConnection() {
    
    var netpage = document.getElementById("networkResult");
	netpage.innerHTML = "Requesting connection info...";
	
    function successful(response) {
        netpage.innerHTML = JSON.stringify(response);
    }
    
    var request = navigator.network.connection('palm://com.palm.connectionmanager', successful, {});
}

function networkConnectionType() {
    var netpage = document.getElementById("networkResult");
 	netpage.innerHTML = "Requesting connection type...";

     function successful(response) {
         
 		var connection = {};
            connection[0] = Connection.UNKNOWN;
            connection[1] = Connection.ETHERNET;
            connection[2] = Connection.WIFI;
            connection[3] = Connection.CELL_2G;
            connection[4] = Connection.CELL_3G;
            connection[5] = Connection.CELL_4G;
            connection[6] = Connection.NONE;
         
         	var r = JSON.stringify(connection[response]);
         	netpage.innerHTML = "connection type: ";
    		netpage.innerHTML += r.replace(/,/g, ', ');
     }

     var request = navigator.network.connection.type('palm://com.palm.connectionmanager', successful, {});    
}

function displayCurrentOrientation() {
	navigator.notification.showBanner(navigator.orientation.getCurrentOrientation(), 'current orientaiton'); 
}	

function getPicture() {
	page('camera');
	var cameraPage = lastpage;
	lastpage.innerHTML = "camera application should launch if this works";
	
	function onSuccessCallback(response) {
		console.log("camera launched successfully");
		navigator.notification.showBanner("camera launched successfully");
	}
	
	function onErrorCallback(response) {
		console.log("camera failed to launch");
		navigator.notification.showBanner("camera failed to launch");
	}
	
	navigator.camera.getPicture(onSuccessCallback, onErrorCallback);
}

window.addEventListener("palmsystem", function(e) {
	console.log("system message: " + JSON.stringify(e.data));
});

window.addEventListener("appmenuopen", function() {
	menu(true);
});

window.addEventListener("back", function() {
	console.log("back gesture");
});

window.addEventListener("forward", function() {
	console.log("forward gesture");
});

function menu() {
	var menudiv = document.getElementById('menu');
	if (typeof state == 'undefined')
		var state = (menudiv.style.display != 'block');
		
	menudiv.style.display = state ? 'block' : 'none';
}

lastreq = null;
function launchmap() {
	navigator.map.show();
	menu(false);
}

var lastpage = document.getElementById('screen');

function page(id) {
	lastpage.style.display = 'none';
	lastpage = document.getElementById(id);
	lastpage.style.display = 'block';
	menu(false);
}
	
</script>


</body>
</html>
