/*
* This file is part of the Doodle3D project (http://doodle3d.com).
*
* Copyright (c) 2013, Doodle3D
* This software is licensed under the terms of the GNU GPL v2 or later.
* See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
*/
function NetworkPanel() {
var NOT_CONNECTED = "not connected"; // used as first item in networks list
// network mode
NetworkPanel.NETWORK_MODE = {
NEITHER: "neither",
CLIENT: "clientMode",
ACCESS_POINT: "accessPointMode"
};
var _networkMode = NetworkPanel.NETWORK_MODE.NEITHER;
var _networkModeChangedHandler;
var _form = new FormPanel();
var _api = new NetworkAPI();
var _networks = {};
var _currentNetwork; // the ssid of the network the box is on
var _selectedNetwork; // the ssid of the selected network in the client mode settings
var _substituted_ssid; // the substituted ssid (displayed during creation)
var _currentLocalIP = "";
var _currentAP;
var _currentNetworkStatus;
var _retryDelay = 2000;
//var _retryRefreshNetworksDelay;
var _retryRetrieveStatusDelayTime = 1000;
var _retryRetrieveStatusDelay;
// after switching wifi network or creating a access point we delay the status retrieval
// because the webserver needs time to switch
var _retrieveNetworkStatusDelayTime = 1000;
var _retrieveNetworkStatusDelay;
// ui elements
var _element;
var _networkSelector;
var _apFieldSet;
var _clientFieldSet;
var _apRadioButton;
var _clientRadioButton;
var _btnRefresh
var _btnConnect;
var _btnCreate;
var _passwordField;
var _passwordLabel;
var _clientStateDisplay;
var _apModeStateDisplay;
var _self = this;
this.init = function(wifiboxURL,wifiboxCGIBinURL,panelElement) {
//console.log("NetworkPanel:init");
_form.init(wifiboxURL,wifiboxCGIBinURL,panelElement)
_api.init(wifiboxURL,wifiboxCGIBinURL);
_element = panelElement;
_apRadioButton = _element.find("#ap");
_clientRadioButton = _element.find("#client");
_btnRefresh = _element.find("#refreshNetworks");
_btnConnect = _element.find("#connectToNetwork");
_btnCreate = _element.find("#createAP");
_networkSelector = _element.find("#network");
_apFieldSet = _element.find("#apSettings");
_clientFieldSet = _element.find("#clientSettings");
_passwordField = _element.find("#password");
_passwordLabel = _element.find("#passwordLabel");
_clientStateDisplay = _element.find("#clientModeState");
_apModeStateDisplay = _element.find("#apModeState");
_apRadioButton.parent().on('touchstart mousedown',showAPSettings);
_clientRadioButton.parent().on('touchstart mousedown',showClientSettings);
_btnRefresh.on('touchstart mousedown',onRefreshClick);
_btnConnect.on('touchstart mousedown',_self.connectToNetwork);
_btnCreate.on('touchstart mousedown',_self.createAP);
_networkSelector.change(networkSelectorChanged);
}
/*
* Handlers
*/
function showAPSettings() {
_apFieldSet.show();
_clientFieldSet.hide();
};
function showClientSettings() {
_clientFieldSet.show();
_apFieldSet.hide();
};
function onRefreshClick() {
_btnRefresh.attr("disabled", true);
_self.refreshNetworks(function() {
_btnRefresh.removeAttr("disabled");
})
}
function networkSelectorChanged(e) {
var selectedOption = $(this).find("option:selected");
_self.selectNetwork(selectedOption.val());
};
this.update = function() {
//console.log("NetworkPanel:update");
_self.refreshNetworks();
_self.retrieveNetworkStatus(false);
}
this.refreshNetworks = function(completeHandler) {
//console.log("NetworkPanel:refreshNetworks");
_api.scan(function(data) { // completed
//console.log("NetworkPanel:scanned");
_networks = {};
var foundCurrentNetwork = false;
// fill network selector
_networkSelector.empty();
_networkSelector.append(
$("").val(NOT_CONNECTED).html(NOT_CONNECTED)
);
$.each(data.networks, function(index,element) {
if(element.ssid == _currentNetwork) {
foundCurrentNetwork = true;
}
_networkSelector.append(
$("").val(element.ssid).html(element.ssid)
);
_networks[element.ssid] = element;
});
if(foundCurrentNetwork) {
_networkSelector.val(_currentNetwork);
_self.selectNetwork(_currentNetwork);
}
if(completeHandler) completeHandler();
}/*,
function() { // failed
clearTimeout(_retryRefreshNetworksDelay);
_retryRetrieveStatusDelay = setTimeout(function() { _self.refreshNetworks(completeHandler); },_retryDelay); // retry after delay
}*/);
};
this.retrieveNetworkStatus = function(connecting) {
//console.log("NetworkPanel:retrieveNetworkStatus");
_api.status(function(data) {
if(data.status === "") {
data.status = NetworkAPI.STATUS.CREATED.toString();
}
if(typeof data.status === 'string') {
data.status = parseInt(data.status);
}
//console.log("NetworkPanel:retrievedStatus status: ",data.status,data.statusMessage);
// if status changed
if(data.status != _currentNetworkStatus) {
// Determine which network mode ui to show
switch(data.status) {
case NetworkAPI.STATUS.NOT_CONNECTED:
setNetworkMode(NetworkPanel.NETWORK_MODE.NEITHER);
break;
case NetworkAPI.STATUS.CONNECTING_FAILED:
case NetworkAPI.STATUS.CONNECTING:
case NetworkAPI.STATUS.CONNECTED:
setNetworkMode(NetworkPanel.NETWORK_MODE.CLIENT);
break;
case NetworkAPI.STATUS.CREATING:
case NetworkAPI.STATUS.CREATED:
setNetworkMode(NetworkPanel.NETWORK_MODE.ACCESS_POINT);
break;
}
// update info
switch(data.status) {
case NetworkAPI.STATUS.CONNECTED:
_currentNetwork = data.ssid;
_currentLocalIP = data.localip;
_self.selectNetwork(data.ssid);
break;
case NetworkAPI.STATUS.CONNECTING_FAILED:
case NetworkAPI.STATUS.CONNECTING:
_currentLocalIP = "";
break;
case NetworkAPI.STATUS.CREATING:
case NetworkAPI.STATUS.CREATED:
_currentNetwork = undefined;
_self.selectNetwork(NOT_CONNECTED);
if(data.ssid && data.status == NetworkAPI.STATUS.CREATED) {
_currentAP = data.ssid;
}
break;
}
// update ui
updateClientModeUI(data.status,data.statusMessage);
updateAPModeUI(data.status,"");
}
// Keep checking for updates?
if(connecting) {
switch(data.status) {
case NetworkAPI.STATUS.CONNECTING:
case NetworkAPI.STATUS.CREATING:
clearTimeout(_retryRetrieveStatusDelay);
_retryRetrieveStatusDelay = setTimeout(function() { _self.retrieveNetworkStatus(connecting); },_retryRetrieveStatusDelayTime); // retry after delay
break;
}
}
_currentNetworkStatus = data.status;
}, function() {
//console.log("NetworkPanel:retrieveStatus failed");
clearTimeout(_retryRetrieveStatusDelay);
_retryRetrieveStatusDelay = setTimeout(function() { _self.retrieveNetworkStatus(connecting); }, _retryRetrieveStatusDelayTime); // retry after delay
});
};
function setNetworkMode(mode) {
//console.log("NetworkPanel:setNetworkMode: ",_networkMode,">",mode);
if(mode == _networkMode) return;
switch(mode) {
case NetworkPanel.NETWORK_MODE.NEITHER:
_apFieldSet.show();
_clientFieldSet.show();
break;
case NetworkPanel.NETWORK_MODE.CLIENT:
_clientRadioButton.prop('checked',true);
_apFieldSet.hide();
_clientFieldSet.show();
break;
case NetworkPanel.NETWORK_MODE.ACCESS_POINT:
_apRadioButton.prop('checked',true);
_apFieldSet.show();
_clientFieldSet.hide();
break;
}
_networkMode = mode;
if(_networkModeChangedHandler) _networkModeChangedHandler(_networkMode);
}
this.selectNetwork = function(ssid) {
//console.log("NetworkPanel:selectNetwork: ",ssid);
if(ssid == "") return;
_selectedNetwork = ssid;
var network = _networks[ssid];
if(network === undefined || network.encryption == "none") {
_passwordLabel.hide();
_passwordField.hide();
} else {
_passwordLabel.show();
_passwordField.show();
}
_passwordField.val("");
};
function updateClientModeUI(state,statusMessage) {
//console.log("NetworkPanel:updateClientModeUI ",state,statusMessage);
var msg = "";
switch(state) {
case NetworkAPI.STATUS.NOT_CONNECTED:
case NetworkAPI.STATUS.CREATING:
case NetworkAPI.STATUS.CREATED:
_btnConnect.removeAttr("disabled");
msg = "Not connected";
_networkSelector.val(NOT_CONNECTED);
break;
case NetworkAPI.STATUS.CONNECTED:
_btnConnect.removeAttr("disabled");
msg = "Connected to: "+_currentNetwork+".";
if(_currentLocalIP != undefined && _currentLocalIP != "") {
var a = ""+_currentLocalIP+"";
msg += " (IP: "+a+")";
}
_networkSelector.val(_currentNetwork);
break;
case NetworkAPI.STATUS.CONNECTING:
_btnConnect.attr("disabled", true);
msg = "Connecting... Reconnect by connecting your device to "+_selectedNetwork+" and going to connect.doodle3d.com";
break;
case NetworkAPI.STATUS.CONNECTING_FAILED:
_btnConnect.removeAttr("disabled");
msg = statusMessage;
break;
}
//console.log(" client display msg: ",msg);
_clientStateDisplay.html(msg);
};
function updateAPModeUI(state,statusMessage) {
var msg = "";
switch(state) {
case NetworkAPI.STATUS.CONNECTING_FAILED:
case NetworkAPI.STATUS.NOT_CONNECTED:
case NetworkAPI.STATUS.CONNECTING:
case NetworkAPI.STATUS.CONNECTED:
_btnCreate.removeAttr("disabled");
msg = "Not currently a access point";
break;
case NetworkAPI.STATUS.CREATED:
_btnCreate.removeAttr("disabled");
msg = "Is access point: "+_currentAP+"";
break;
case NetworkAPI.STATUS.CREATING:
_btnCreate.attr("disabled", true);
msg = "Creating access point... Reconnect by connecting your device to "+_substituted_ssid+" and going to draw.doodle3d.com";
break;
}
//console.log(" ap display msg: ",msg);
_apModeStateDisplay.html(msg);
};
this.connectToNetwork = function() {
//console.log("NetworkPanel:connectToNetwork");
if(_selectedNetwork == undefined) return;
// save network related settings and on complete, connect to network
_form.saveSettings(_form.readForm(),function(validated, data) {
if(!validated) return;
updateClientModeUI(NetworkAPI.STATUS.CONNECTING,"");
_api.associate(_selectedNetwork,_passwordField.val(),true);
// after switching wifi network or creating a access point we delay the status retrieval
// because the webserver needs time to switch it's status
clearTimeout(_retrieveNetworkStatusDelay);
_retrieveNetworkStatusDelay = setTimeout(function() { _self.retrieveNetworkStatus(true); }, _retrieveNetworkStatusDelayTime);
});
};
this.createAP = function() {
//console.log("createAP");
// save network related settings and on complete, create access point
_form.saveSettings(_form.readForm(),function(validated, data) {
if(!validated) return;
_substituted_ssid = data.substituted_ssid;
updateAPModeUI(NetworkAPI.STATUS.CREATING,"");
_api.openAP();
// after switching wifi network or creating a access point we delay the status retrieval
// because the webserver needs time to switch it's status
clearTimeout(_retrieveNetworkStatusDelay);
_retrieveNetworkStatusDelay = setTimeout(function() { _self.retrieveNetworkStatus(true); }, _retrieveNetworkStatusDelayTime);
});
};
this.setNetworkModeChangedHandler = function(handler) {
_networkModeChangedHandler = handler;
}
}