<commit_before>/**
 * @author <NAME>
 */

var baseURL = "http://findaminemo.web709.discountasp.net/API/findamine.svc"
Ti.include("/lib/version.js");

function makeClueXML(clue) 
{
	var moment = require('lib/moment.min');
	var startTime, solvedTime;
	if (clue.StartTime != 0) {
		startTime = moment(clue.StartTime, "YYYY-MM-DD HH:mm:ss");
	} else {
		startTime = moment(0);
	}
	var formattedStartTime = startTime.format("MM/DD/YYYY hh:mm:ss a");
	
	if (clue.SolvedTime != 0) {
		solvedTime = moment(clue.SolvedTime, "YYYY-MM-DD HH:mm:ss");
	} else {
		solvedTime = moment(0);
	}
	var formattedSolvedTime = solvedTime.format("MM/DD/YYYY hh:mm:ss a");

	var xml = "<ArrayOfCompletedClue xmlns=\"http://www.findamine.mobi/API\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
	xml += "<CompletedClue>";
	
	// Add array of locations
	xml += "<CompletedClue_breadcrumbs>";
	for (var i = 0; i < clue.locations.length; i++) {
		var locationTimestamp = moment(clue.locations[i].timestamp, "YYYY-MM-DD HH:mm:ss");
		var formattedLocationTimestamp = locationTimestamp.format("MM/DD/YYYY hh:mm:ss a");
		Ti.API.info(clue.locations[i].timestamp);
		Ti.API.info(locationTimestamp);
		Ti.API.info(formattedLocationTimestamp);
		xml += "<Breadcrumb>";
		xml += "<Breadcrumb_latitude>" + clue.locations[i].latitude + "</Breadcrumb_latitude>";
		xml += "<Breadcrumb_longitude>" + clue.locations[i].longitude + "</Breadcrumb_longitude>";
		xml += "<Breadcrumb_timestamp>" + formattedLocationTimestamp + "</Breadcrumb_timestamp>";
		xml += "</Breadcrumb>";
	}
	xml += "</CompletedClue_breadcrumbs>";
	
	// General clue properties
	xml += "<CompletedClue_clue_ID>" + clue.OnlineId + "</CompletedClue_clue_ID>";
	xml += "<CompletedClue_date_finished>" + formattedSolvedTime + "</CompletedClue_date_finished>";
	xml += "<CompletedClue_date_started>" + formattedStartTime + "</CompletedClue_date_started>";
	xml += "<CompletedClue_hint_level></CompletedClue_hint_level>";
	xml += "<CompletedClue_hot_cold_level></CompletedClue_hot_cold_level>";
	xml += "<CompletedClue_location_order></CompletedClue_location_order>";
	xml += "<CompletedClue_location_started></CompletedClue_location_started>";
	xml += "<CompletedClue_points_earned></CompletedClue_points_earned>";
	
	// Add array of question responses
	xml += "<CompletedClue_question_responses>";
	for (var i = 0; i < clue.questions.length; i++) {
		var questionTimestamp = moment(clue.questions[i].Timestamp);
		var formattedQuestionTimestamp = questionTimestamp.format("MM/DD/YYYY hh:mm:ss a");
		xml += "<QuestionResponse>";
		xml += "<QuestionResponse_answer_boolean></QuestionResponse_answer_boolean>";
		xml += "<QuestionResponse_answer_integer></QuestionResponse_answer_integer>";
		xml += "<QuestionResponse_answer_text>" + clue.questions[i].Answer + "</QuestionResponse_answer_text>";
		xml += "<QuestionResponse_date_answered>" + formattedQuestionTimestamp + "</QuestionResponse_date_answered>";
		xml += "<QuestionResponse_question_ID>" + clue.questions[i].OnlineId + "</QuestionResponse_question_ID>";
		xml += "</QuestionResponse>";
	}
	xml += "</CompletedClue_question_responses>";
	xml += "<CompletedClue_share_level></CompletedClue_share_level>";
	xml += "</CompletedClue></ArrayOfCompletedClue>";
	return xml;
}

exports.getGameID = function() {
	if (Ti.App.Properties.hasProperty("gameID")) {
		return Ti.App.Properties.getString("gameID");
	}

	return -1;
}

exports.authenticate = function(username, password) {
	Ti.API.info("api.authenticate: Attempting to authenticate with web service.");
	var hashedPassword = Ti.Utils.sha1(password);
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info("api.authenticate: " + this.responseText);
			var json = JSON.parse(this.responseText);
			var value = 1;
			if (json.valid.toLowerCase() == "true") {
				Ti.App.Properties.setString("username", username);
				Ti.App.Properties.setString("hashedPassword", <PASSWORD>);
				Ti.App.Properties.setString("gameID", json.gameId);
				Ti.App.Properties.setBool("loggedIn", true);
				value = 0;
			}
			Ti.App.fireEvent("apiAuthenticate", {value: value});
    	},
    	onerror: function(e) {
    		Ti.API.info("api.authenticate network error:")
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			Ti.App.fireEvent("apiAuthenticate", {value: 2});
    	},
    	timeout:30000
	});
	var url = baseURL + "/Authenticate?format=json&username=" + username + "&password=" + <PASSWORD>;
	Ti.API.info("api.authenticate: " + url);
	xhr.open('GET', url);
	xhr.send();
}

exports.getAvailableHunts = function() {
	Ti.API.info("api.getAvailableHunts: Attempting to get ALL available hunts from web service.");
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info("api.getAvailableHunts: " + this.responseText);
			var json = JSON.parse(this.responseText);
			if ("code" in json) { // json.hasOwnProperty("code")
				// This means we successfully got data from the web service, but it returned an error
				Ti.App.fireEvent("GotHuntsFromWebService", {error: 1, data: {'code': json.code, 'domain': json.domain, 'fullDescription': json.fullDescription, 'localizedDescription': json.localizedDescription}});
			} else {
				Ti.App.fireEvent("GotHuntsFromWebService", {error: 0, data: json});
			}
    	},
    	onerror: function(e) {
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			Ti.App.fireEvent("GotHuntsFromWebService", {error: 2, data: {'status': this.status, 'responseText': this.responseText, 'error': e.error}});
    	},
    	timeout:30000
	});
	var authenticate = require('lib/authenticate');
	var gameID = exports.getGameID();
	var username = authenticate.getUserName();
	var hashedPassword = authenticate.getHashedPassword();
	var url = baseURL + "/GetActiveHunts?format=json&gameID=" + gameID + "&username=" + username + "&password=" + <PASSWORD>Password;
	Ti.API.info("api.getAvailableHunts: " + url);
	xhr.open('GET', url);
	xhr.send();
}

exports.uploadImage = function(huntid, finalClueOnlineId, imageData, retryOnFail)
{
	Ti.API.info("api.uploadImage: Uploading image. finalClueOnlineId = " + finalClueOnlineId);
	var db = require('lib/database');
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info(this.responseText);
			Ti.API.info("api.uploadImage(): Upload success.")
			db.markUploadImageSuccess(huntid);
    	},
    	onerror: function(e) {
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			if (retryOnFail) {
				db.markUploadImageError(huntid);
			}
    	},
    	timeout:30000
	});
	var authenticate = require('lib/authenticate');
	var username = authenticate.getUserName();
	var hashedPassword = authenticate.getHashedPassword();
	var url = baseURL + "/UploadImage?clueID=" + finalClueOnlineId + "&fileExtension=png&username=" + username + "&password=" + <PASSWORD>;
	Ti.API.info("api.getAvailableHunts: " + url);
	xhr.open('POST', url);
	if (android) {
		xhr.setRequestHeader("Content-Type", "multipart/form-data");		
	} else {
		xhr.setRequestHeader("Content-Type", "text/plain");
	}
	//xhr.setRequestHeader("enctype", "multipart/form-data");
    //xhr.setRequestHeader("Content-Type", "image/png");
	//xhr.setRequestHeader("Content-Length", imageData.size);
	xhr.send(imageData);
}

exports.uploadClue = function(clue, retryOnFail) 
{
	Ti.API.info("api.uploadClue: Uploading clue to web service.");
	var db = require('lib/database');
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info(this.responseText);
			Ti.API.info("api.uploadClue(): Upload success.");
			db.markUploadSuccess(clue.id, clue.locations);
    	},
    	onerror: function(e) {
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			if (retryOnFail) {		
				db.markUploadError(clue.id);
			}<commit_msg>Made changes to the ImageUpload function to accomodate extensions for different image types.<commit_after>/**
 * @author <NAME>
 */

var baseURL = "http://findaminemo.web709.discountasp.net/API/findamine.svc"
Ti.include("/lib/version.js");

function makeClueXML(clue) 
{
	var moment = require('lib/moment.min');
	var startTime, solvedTime;
	if (clue.StartTime != 0) {
		startTime = moment(clue.StartTime, "YYYY-MM-DD HH:mm:ss");
	} else {
		startTime = moment(0);
	}
	var formattedStartTime = startTime.format("MM/DD/YYYY hh:mm:ss a");
	
	if (clue.SolvedTime != 0) {
		solvedTime = moment(clue.SolvedTime, "YYYY-MM-DD HH:mm:ss");
	} else {
		solvedTime = moment(0);
	}
	var formattedSolvedTime = solvedTime.format("MM/DD/YYYY hh:mm:ss a");

	var xml = "<ArrayOfCompletedClue xmlns=\"http://www.findamine.mobi/API\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
	xml += "<CompletedClue>";
	
	// Add array of locations
	xml += "<CompletedClue_breadcrumbs>";
	for (var i = 0; i < clue.locations.length; i++) {
		var locationTimestamp = moment(clue.locations[i].timestamp, "YYYY-MM-DD HH:mm:ss");
		var formattedLocationTimestamp = locationTimestamp.format("MM/DD/YYYY hh:mm:ss a");
		Ti.API.info(clue.locations[i].timestamp);
		Ti.API.info(locationTimestamp);
		Ti.API.info(formattedLocationTimestamp);
		xml += "<Breadcrumb>";
		xml += "<Breadcrumb_latitude>" + clue.locations[i].latitude + "</Breadcrumb_latitude>";
		xml += "<Breadcrumb_longitude>" + clue.locations[i].longitude + "</Breadcrumb_longitude>";
		xml += "<Breadcrumb_timestamp>" + formattedLocationTimestamp + "</Breadcrumb_timestamp>";
		xml += "</Breadcrumb>";
	}
	xml += "</CompletedClue_breadcrumbs>";
	
	// General clue properties
	xml += "<CompletedClue_clue_ID>" + clue.OnlineId + "</CompletedClue_clue_ID>";
	xml += "<CompletedClue_date_finished>" + formattedSolvedTime + "</CompletedClue_date_finished>";
	xml += "<CompletedClue_date_started>" + formattedStartTime + "</CompletedClue_date_started>";
	xml += "<CompletedClue_hint_level></CompletedClue_hint_level>";
	xml += "<CompletedClue_hot_cold_level></CompletedClue_hot_cold_level>";
	xml += "<CompletedClue_location_order></CompletedClue_location_order>";
	xml += "<CompletedClue_location_started></CompletedClue_location_started>";
	xml += "<CompletedClue_points_earned></CompletedClue_points_earned>";
	
	// Add array of question responses
	xml += "<CompletedClue_question_responses>";
	for (var i = 0; i < clue.questions.length; i++) {
		var questionTimestamp = moment(clue.questions[i].Timestamp);
		var formattedQuestionTimestamp = questionTimestamp.format("MM/DD/YYYY hh:mm:ss a");
		xml += "<QuestionResponse>";
		xml += "<QuestionResponse_answer_boolean></QuestionResponse_answer_boolean>";
		xml += "<QuestionResponse_answer_integer></QuestionResponse_answer_integer>";
		xml += "<QuestionResponse_answer_text>" + clue.questions[i].Answer + "</QuestionResponse_answer_text>";
		xml += "<QuestionResponse_date_answered>" + formattedQuestionTimestamp + "</QuestionResponse_date_answered>";
		xml += "<QuestionResponse_question_ID>" + clue.questions[i].OnlineId + "</QuestionResponse_question_ID>";
		xml += "</QuestionResponse>";
	}
	xml += "</CompletedClue_question_responses>";
	xml += "<CompletedClue_share_level></CompletedClue_share_level>";
	xml += "</CompletedClue></ArrayOfCompletedClue>";
	return xml;
}

exports.getGameID = function() {
	if (Ti.App.Properties.hasProperty("gameID")) {
		return Ti.App.Properties.getString("gameID");
	}

	return -1;
}

exports.authenticate = function(username, password) {
	Ti.API.info("api.authenticate: Attempting to authenticate with web service.");
	var hashedPassword = Ti.Utils.sha1(password);
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info("api.authenticate: " + this.responseText);
			var json = JSON.parse(this.responseText);
			var value = 1;
			if (json.valid.toLowerCase() == "true") {
				Ti.App.Properties.setString("username", username);
				Ti.App.Properties.setString("hashedPassword", <PASSWORD>);
				Ti.App.Properties.setString("gameID", json.gameId);
				Ti.App.Properties.setBool("loggedIn", true);
				value = 0;
			}
			Ti.App.fireEvent("apiAuthenticate", {value: value});
    	},
    	onerror: function(e) {
    		Ti.API.info("api.authenticate network error:")
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			Ti.App.fireEvent("apiAuthenticate", {value: 2});
    	},
    	timeout:30000
	});
	var url = baseURL + "/Authenticate?format=json&username=" + username + "&password=" + hashedPassword;
	Ti.API.info("api.authenticate: " + url);
	xhr.open('GET', url);
	xhr.send();
}

exports.getAvailableHunts = function() {
	Ti.API.info("api.getAvailableHunts: Attempting to get ALL available hunts from web service.");
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info("api.getAvailableHunts: " + this.responseText);
			var json = JSON.parse(this.responseText);
			if ("code" in json) { // json.hasOwnProperty("code")
				// This means we successfully got data from the web service, but it returned an error
				Ti.App.fireEvent("GotHuntsFromWebService", {error: 1, data: {'code': json.code, 'domain': json.domain, 'fullDescription': json.fullDescription, 'localizedDescription': json.localizedDescription}});
			} else {
				Ti.App.fireEvent("GotHuntsFromWebService", {error: 0, data: json});
			}
    	},
    	onerror: function(e) {
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			Ti.App.fireEvent("GotHuntsFromWebService", {error: 2, data: {'status': this.status, 'responseText': this.responseText, 'error': e.error}});
    	},
    	timeout:30000
	});
	var authenticate = require('lib/authenticate');
	var gameID = exports.getGameID();
	var username = authenticate.getUserName();
	var hashedPassword = authenticate.getHashedPassword();
	var url = baseURL + "/GetActiveHunts?format=json&gameID=" + gameID + "&username=" + username + "&password=" + <PASSWORD>;
	Ti.API.info("api.getAvailableHunts: " + url);
	xhr.open('GET', url);
	xhr.send();
}

exports.uploadImage = function(huntid, finalClueOnlineId, imageData, retryOnFail)
{
	Ti.API.info("api.uploadImage: Uploading image. finalClueOnlineId = " + finalClueOnlineId);
	var db = require('lib/database');
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info(this.responseText);
			Ti.API.info("api.uploadImage(): Upload success.")
			db.markUploadImageSuccess(huntid);
    	},
    	onerror: function(e) {
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			if (retryOnFail) {
				db.markUploadImageError(huntid);
			}
    	},
    	timeout:30000
	});
	var authenticate = require('lib/authenticate');
	var username = authenticate.getUserName();
	var hashedPassword = authenticate.<PASSWORD>();
	var fileExtension;
	switch(true){
		case (imageData.mimeType.indexOf('bmp') > -1 || imageData.mimeType.indexOf('bitmap') > -1):
			fileExtension = 'bmp';
			break;
		case (imageData.mimeType.indexOf('gif') > -1):
			fileExtension = 'gif';
			break;
		case (imageData.mimeType.indexOf('jpeg') > -1):
			fileExtension = 'jpg';
			break;
		case (imageData.mimeType.indexOf('png') > -1):
			fileExtension = 'png';
			break;
		case (imageData.mimeType.indexOf('tiff') > -1):
			fileExtension = 'tif';
			break;
	}
	var url = baseURL + "/UploadImage?clueID=" + finalClueOnlineId + "&fileExtension=" + fileExtension + "&username=" + username + "&password=" + <PASSWORD>;
	Ti.API.info("api.getAvailableHunts: " + url);
	xhr.open('POST', url);
	/*if (android) {
		xhr.setRequestHeader("Content-Type", "multipart/form-data");		
	} else {*/
		xhr.setRequestHeader("Content-Type", "text/plain");
	//}
	//xhr.setRequestHeader("enctype", "multipart/form-data");
    //xhr.setRequestHeader("Content-Type", "image/png");
	//xhr.setRequestHeader("Content-Length", imageData.size);
	xhr.send(imageData);
}

exports.uploadClue = function(clue, retryOnFail) 
{
	Ti.API.info("api.uploadClue: Uploading clue to web service.");
	var db = require('lib/database');
	
	var xhr = Ti.Network.createHTTPClient({
    	onload: function() {
			Ti.API.info(this.responseText);
			Ti.API.info("api.uploadClue(): Upload success.");
			db.markUploadSuccess(clue.id, clue.locations);
    	},
    	onerror: function(e) {
			Ti.API.info("STATUS: " + this.status);
			Ti.API.info("TEXT:   " + this.responseText);
			Ti.API.info("ERROR:  " + e.error);
			if (retryOnFail) {		
				db.markUploadError(clue.id);
			}
{'fraction_non_alphanumeric': 0.17048984468339307, 'fraction_numerical': 0.0047789725209080045, 'mean_word_length': 4.766792972786773, 'pattern_counts': {'":': 0, '<': 109, '<?xml version=': 0, '>': 111, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 62}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6570968', 'n_tokens_mistral': 6215, 'n_tokens_neox': 5652, 'n_words': 965}