<!--

 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>
<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>      
