<!DOCTYPE html>
<!--

 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.

-->


<html>
  <head>
    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
    <title>Cordova Mobile Spec</title>
    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
    <script type="text/javascript" charset="utf-8" src="../cordova.js"></script>      

      
<script type="text/javascript" charset="utf-8">

    var deviceReady = false;

    //-------------------------------------------------------------------------
    // HTML5 Database
    //-------------------------------------------------------------------------
    var db;
    var callDatabase = function() {
        db = openDatabase("mydb", "1.0", "Apache Cordova Demo", 20000);
        if (db === null) {
            databaseOutput("Database could not be opened.");
            return;
        }
        databaseOutput("Database opened.");
        db.transaction(function (tx) {
            tx.executeSql('DROP TABLE IF EXISTS DEMO');
            tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)', [],
                 function(tx,results) { console.log("Created table"); },
                 function(tx,err) { alert("Error creating table: "+err.message); });
            tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")', [],
                 function(tx,results) { console.log("Insert row1 success"); },
                 function(tx,err) { alert("Error adding 1st row: "+err.message); });
            tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")', [],
                 function(tx,results) { console.log("Insert row2 success"); },
                 function(tx,err) { alert("Error adding 2nd row: "+err.message); });
            databaseOutput("Data written to DEMO table.");
            console.log("Data written to DEMO table.");

            tx.executeSql('SELECT * FROM DEMO', [], function (tx, results) {
                var len = results.rows.length;
                var text = "DEMO table: " + len + " rows found.<br>";
                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
                for (var i=0; i<len; i++){
                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
                }
                text = text + "</table>";
                databaseOutput(text);
            }, function(tx, err) {
                alert("Error processing SELECT * SQL: "+err.message);
            });
            tx.executeSql('SELECT ID FROM DEMO', [], function (tx, results) {
                var len = results.rows.length;
                var text = "DEMO table: " + len + " rows found.<br>";
                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
                for (var i=0; i<len; i++){
                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + "</td></tr>";
                }
                text = text + "</table>";
                databaseOutput(text);
            }, function(tx, err) {
                alert("Error processing SELECT ID SQL: "+err.message);
            });
            
        },
        function(err) {
            console.log("Transaction failed: " + err.message);
        });


    };

    var readDatabase = function() {
    	if (!db) {
    	    db = openDatabase("mydb", "1.0", "Apache Cordova Demo", 20000);
    	    if (db === null) {
                databaseOutput("Database could not be opened.");
                return;
    	    }
        }
        db.transaction(function (tx) {
            tx.executeSql('SELECT * FROM DEMO WHERE id=2', [], function (tx, results) {
                var len = results.rows.length;
                var text = "DEMO table: " + len + " rows found.<br>";
                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
                for (var i=0; i<len; i++){
                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
                }
                text = text + "</table>";
                databaseOutput(text);
            }, function(tx, err) {
                alert("Error processing SELECT * WHERE id=2 SQL: "+err.message);
            });
        });
    }

    var databaseOutput = function(s) {
        var el = document.getElementById("database_results");
        el.innerHTML = el.innerHTML + s + "<br>";
    };
    
    /**
     * Function called when page has finished loading.
     */
    function init() {
        document.addEventListener("deviceready", function() {
                deviceReady = true;
                console.log("Device="+device.platform+" "+device.version);
            }, false);
        window.setTimeout(function() {
        	if (!deviceReady) {
        		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
        	}
        },1000);
    }

</script>

  </head>
  <body onload="init();" id="stage" class="theme">
  
    <h1>HTML5 Database</h1>   
    <div id="info">
        <b>Results:</b><br>
        <span id="database_results"></span>
    </div>
    <h2>Action</h2>
    <div class="btn large" onclick="callDatabase();">Create, Add, Read Database</div>
    <div class="btn large" onclick="readDatabase();">Read Database</div>
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>    
  </body>
</html>      
