'use strict';

var undefined;

/**
 *
 * @param settings
 * @constructor
 */
function OauthAccess(settings) {
	OauthAccess.extend(this, settings);
}


OauthAccess.extend = function (target, obj) {
	for(var key in obj) {
		if (obj.hasOwnProperty(key)) {
			target[key] = obj[key];
		}
	}
};


/**
 * Converts a data object into an array
 *
 * @param obj
 * @returns {Array}
 */
OauthAccess.arrayify = function (obj) {
	if (typeof obj != 'object') {
		throw 'Data must be an [object]'
	}

	var arr = [];
	for (var key in obj) {
		if (obj.hasOwnProperty(key)) {
			arr.push({
				key: key
				, val: obj[key]
			});
		}
	}

	return arr;
};


OauthAccess.generateNonce = function () {
	return Math.random() * 10000000;
};


OauthAccess.generateTimestamp = function () {
	return parseInt((new Date()).getTime()/1000, 10);
};


OauthAccess.serializeParams = function (params) {
	var str = '', i;

	for (i = 0; i < params.length; i++) {
		str += params[i].key + '%3D' + params[i].val;
		if (i < params.length - 1) {
			str += '%26';
		}
	}

	return str;
};


/**
 *
 * @param queryStr
 * @returns {Array}
 */
OauthAccess.parseQueryParams = function (queryStr) {
	var split
	, queryParamsArray = []
	, pairs = queryStr.split('&');

	for (var i = 0; i < pairs.length; i++) {
		split = pairs[i].split('=');
		queryParamsArray.push({key: split[0], val: split[1]});
	}

	return queryParamsArray;
};


OauthAccess.encodeParams = function (params) {
	var i, newParams = [];

	for (i = 0; i < params.length; i++) {
		newParams[i] = {
			key: encodeURIComponent(params[i].key)
			, val: encodeURIComponent(params[i].val)
		};
	}

	return newParams;
};


OauthAccess.sortParams = function (params) {
	return params.sort(function (a, b) {
		var aKey = a.key, bKey = b.key;

		if (aKey < bKey) {
			return -1;
		}

		if (aKey > bKey) {
			return 1;
		}

		return 0;
	});
};


/**
 *
 * @param {String} httpMethod
 * @param {String} baseUrl
 * @param {Array} params
 * @param {String} nonce
 * @param {String} timestamp
 * @param {String} encToken
 * @param {String} encTokenSecret
 * @param {String} encKey
 * @param {String} encCallback
 * @return {String}
 */
OauthAccess.generateSignature = function (httpMethod, baseUrl, params, nonce, timestamp, encToken, encTokenSecret, encKey, encCallback) {
	var base;

	params.push({key: 'oauth_callback', val: encCallback});
	params.push({key: 'oauth_consumer_key', val: encKey});
	params.push({key: 'oauth_nonce', val: nonce});
	params.push({key: 'oauth_signature_method', val: 'HMAC-SHA1-QI'});
	params.push({key: 'oauth_timestamp', val: timestamp});
	params.push({key: 'oauth_token', val: encToken});
	params.push({key: 'oauth_version', val: '1.0'});

	params = OauthAccess.sortParams(params);
	params = OauthAccess.encodeParams(params);
	params = OauthAccess.serializeParams(params);

	base = httpMethod.toUpperCase() + '&' + encodeURIComponent(baseUrl).toString() + '&' + params;
	return b64_hmac_sha1(encTokenSecret, base) + '=';
};


/**
 *
 * @param httpMethod
 * @param url
 * @param params
 * @param token
 * @param tokenSecret
 * @param key
 * @param callback
 * @returns {string}
 */
OauthAccess.generateHeader = function (httpMethod, url, params, token, tokenSecret, key, callback) {
	params = params
		? OauthAccess.arrayify(params)
		: [];

	if (typeof httpMethod != 'string') {
		httpMethod = 'GET';
	}

	if (! url) {
		throw 'Unable to generate an authorization header: No "url" provided';
	}

	tokenSecret = tokenSecret || '';
	callback = encodeURIComponent(callback);
	key = encodeURIComponent(key);
	token = encodeURIComponent(token);

	var baseUrl, signature
	, nonce = OauthAccess.generateNonce()
	, timestamp = OauthAccess.generateTimestamp()
	, queryStart = url.indexOf('?');

	if (queryStart > -1) {
		baseUrl = url.slice(0, queryStart);
		params = params.concat(OauthAccess.parseQueryParams(url.slice(queryStart + 1)));
	} else {
		baseUrl = url;
	}

	signature = OauthAccess.generateSignature(httpMethod, baseUrl, params, nonce, timestamp, token, encodeURIComponent(tokenSecret), key, callback);

	return 'OAuth oauth_nonce="' + encodeURIComponent(nonce) +
		'",oauth_callback="' + callback +
		'",oauth_signature_method="HMAC-SHA1-QI"' +
		',oauth_timestamp="' + encodeURIComponent(timestamp) +
		'",oauth_consumer_key="' + key +
		'",oauth_signature="' + signature +
		'",oauth_token="' + token +
		'",oauth_version="1.0"';
};


OauthAccess.prototype = {
	generateHeader: function (httpMethod, baseUrl, params) {
		var accessTokens = this.accessTokens;
		return OauthAccess.generateHeader(httpMethod, baseUrl, params, accessTokens.token, accessTokens.tokenSecret, this.key, this.callback);
	}
};
@@ -12,23 +12,8 @@
 ';%0A%0A
-var undefined;%0A
 %0A/**
@@ -460,16 +460,17 @@
 object%5D'
+;
 %0A%09%7D%0A%0A%09va
@@ -2033,32 +2033,67 @@
  encTokenSecret%0A
+ * @param %7BString%7D signatureMethod%0A
  * @param %7BStrin
@@ -2271,16 +2271,33 @@
 nSecret,
+ signatureMethod,
  encKey,
@@ -2539,22 +2539,23 @@
 al: 
-'HMAC-SHA1-QI'
+signatureMethod
 %7D);%0A
@@ -3087,32 +3087,58 @@
 ram tokenSecret%0A
+ * @param signatureMethod%0A
  * @param key%0A *
@@ -3262,16 +3262,33 @@
 nSecret,
+ signatureMethod,
  key, ca
@@ -4106,16 +4106,33 @@
 Secret),
+ signatureMethod,
  key, ca
@@ -4270,20 +4270,31 @@
 od=%22
-HMAC-SHA1-QI
+' + signatureMethod + '
 %22' +
@@ -4610,16 +4610,16 @@
 Tokens;%0A
-
 %09%09return
@@ -4720,16 +4720,38 @@
 nSecret,
+ this.signatureMethod,
  this.ke

add argument for signatureMethod