'use strict';

// MODULES //

var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; // eslint-disable-line no-unused-vars


// MAIN //

/**
* Returns a getter function for arrays having a specified number of dimensions.
*
* @private
* @param {PositiveInteger} ndims - array dimensions
* @returns {Function} getter
*
* @example
* var f = get( 3 );
* // returns <Function>
*/
function get( ndims ) {
	var n = ndims - 1;
	var f;
	var i;

	// Code generation. Start with function definition...
	f = '(function iife() {return function get(';

	/*
	* Create the index input arguments...
	* > function get( i0, i1, ...) {
	*/
	for ( i = 0; i < ndims; i++ ) {
		f += 'i' + i;
		if ( i < n ) {
			f += ',';
		}
	}
	f += '){';

	// Create the function body...

	/*
	* Type check each index.
	* > if ( !isInteger( i0 ) ) { throw new TypeError( ... ) }
	*/
	for ( i = 0; i < ndims; i++ ) {
		f += 'if (!isInteger(i'+i+')) {throw new TypeError(\'invalid input argument. Indices must be integer valued. Argument: '+i+'. Value: `\'+i'+i+'+\'`.\');}';
	}
	/*
	* Index into the array according to the offset and strides...
	* > return data[offset+strides[0]*i0+strides[1]*i1+...];
	*/
	f += 'return this._buffer[this._offset+';
	for ( i = 0; i < ndims; i++ ) {
		f += 'this._strides['+i+']*i'+i;
		if ( i < n ) {
			f += '+';
		}
	}
	f += '];';

	// Close the function:
	f += '}';

	// Close the IIFE:
	f += '})()';

	// Add a source directive for debugging:
	f += '//# sourceURL=ndarray.ctor.get.js';

	// Create the function in the current scope to allow access to required modules:
	return eval( f ); // eslint-disable-line no-eval

	/*
	* e.g., returns
	*     function get( i0, i1, i2 ) {
	*         if ( !isInteger( i0 ) ) {
	*             throw new TypeError( 'invalid input argument. Indices must be integer valued. Argument: 0. Value: `'+i0+'`.' );
	*         }
	*         if ( !isInteger( i1 ) ) {
	*             throw new TypeError( 'invalid input argument. Indices must be integer valued. Argument: 1. Value: `'+i1+'`.' );
	*         }
	*         if ( !isInteger( i2 ) ) {
	*             throw new TypeError( 'invalid input argument. Indices must be integer valued. Argument: 2. Value: `'+i2+'`.' );
	*         }
	*         return this._buffer[ this._offset + this._strides[0]*i0 + this._strides[1]*i1 + this._strides[2]*i2 ];
	*     }
	*/
} // end FUNCTION get()


// EXPORTS //

module.exports = get;

@@ -129,16 +129,98 @@
 ed-vars%0A
+var getIndex = require( './get_index.js' ); // eslint-disable-line no-unused-vars%0A
 %0A%0A// MAI
@@ -601,17 +601,16 @@
 n iife()
- 
 %7Breturn 
@@ -976,17 +976,16 @@
 f += 'if
- 
 (!isInte
@@ -996,17 +996,16 @@
 i'+i+'))
- 
 %7Bthrow n
@@ -1129,16 +1129,211 @@
 %0A%09%7D%0A%09/*%0A
+%09* Resolve indices based on the index mode.%0A%09* %3E i0 = getIndex( i0, shape%5B0%5D, mode );%0A%09*/%0A%09for ( i = 0; i %3C ndims; i++ ) %7B%0A%09%09f += 'i'+i+'=getIndex(i'+i+',this._shape%5B'+i+'%5D,this._mode);';%0A%09%7D%0A%09/*%0A
 %09* Index
@@ -2467,32 +2467,32 @@
 : %60'+i2+'%60.' );%0A
-
 %09*         %7D%0A%09* 
@@ -2480,32 +2480,218 @@
 );%0A%09*         %7D%0A
+%09*         i0 = getIndex( i0, this._shape%5B 0 %5D, this._mode );%0A%09*         i1 = getIndex( i1, this._shape%5B 1 %5D, this._mode );%0A%09*         i2 = getIndex( i2, this._shape%5B 2 %5D, this._mode );%0A
 %09*         retur

Add support for an index mode