//title: Cast-On Sampler (javascript with knitout module)
// Creates several sheets, all with different cast-ons.

//include knitout module:
const knitout = require('knitout'); //include knitout module
const K = new knitout.Writer({ carriers:['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] });
K.addHeader('Machine', 'SWGN2');

//Parameters:
let carrier = "3"; //carrier name
let min = 1; //needle number of left edge
let max = 20; //needle number of right edge
let rows = 20; //rows of knitting in each sample
let cordWidth = 4; //cord width (for I-cord cast-on)

// === Alternating Tucks === 
//Bring in carrier:
K.inhook(carrier);
//Set stitch table entry for cast-on:
K.stitchNumber(101);

//On SWGN2 machines, carriers start on the right,
//so will start tucking onto needles right-to-left,
//and will be sure to tuck the rightmost needle in the first pass:
for (let n = max; n >= min; n -= 1) {
	//tuck alternating needles, making sure to do the right edge:
	if ((max - n) % 2 === 0) {
		K.tuck("-", 'f' + n, carrier);
	}
}
//now, moving left-to-right, tuck the needles that were not tucked on the first pass:
for (let n = min; n <= max; n += 1) {
	if ((max - n) % 2 !== 0) {
		K.tuck("+", 'f' + n, carrier);
	}
}
//Set stitch table entry for knitting:
K.stitchNumber(105);
//knit two plain rows to allow cast-on stitches to relax:
// two isn't set in stone here -- it's just convenient
// for this example code to have the carrier end up on the right.
for (let n = max; n >= min; n -= 1) {
	K.knit("-", 'f' + n, carrier);
}
//send out yarn inserting hook; it is no longer needed to hold the yarn in place:
K.releasehook(carrier);
for (let n = min; n <= max; n += 1) {
	K.knit("+", 'f' + n, carrier);
}
// ---- single jersey sheet ----
for (let r = 0; r <= rows; r += 1) {
	if (r % 2 === 0) {
		//left-going row:
		for (let n = max; n >= min; n -= 1) {
			K.knit("-", 'f' + n, carrier);
		}
	} else {
		//right-going row:
		for (let n = min; n <= max; n += 1) {
			K.knit("+", 'f' + n, carrier);
		}
	}
}

// ---- take carrier out and drop remaining loops ----
//Take carrier out with yarn inserting hook:
K.outhook(carrier);

//drop loops:
for (let n = min; n <= max; n += 1) {
	K.drop('f' + n);
}

// === All-Needle Welt === 
//Bring in carrier:
K.inhook(carrier);
//Set stitch table entry for cast-on:
K.stitchNumber(101);

//On SWGN2 machines, carriers start on the right,
//so will start by tucking all needles right-to-left,
//and will be sure to tuck the leftmost back-bed needle last.

//Need to use quarter-pitch racking to tuck all needles in one pass:
K.rack(-0.75);

for (let n = max; n >= min; n -= 1) {
	K.tuck("-", 'f' + n, carrier);
	K.tuck("-", 'b' + n, carrier);
}

//Return to aligned racking:
K.rack(0);

//Set stitch table entry for knitting:
K.stitchNumber(105);

//Do a rows of plain knitting on the front and back:
for (let n = min; n <= max; n += 1) {
	K.knit("+", 'f' + n, carrier);
}
for (let n = max; n >= min; n -= 1) {
	K.knit("-", 'b' + n, carrier);
}
//One can knit more on the front or back beds here to make a larger "welt" at the edge.

//Stack back-bed stitches with front-bed stitches:
for (let n = max; n >= min; n -= 1) {
	K.xfer('b' + n, 'f' + n);
}

//knit a plain row through the stacked stitches and return carrier to the right edge:
for (let n = min; n <= max; n += 1) {
	K.knit("+", 'f' + n, carrier);
}

//send out yarn inserting hook; it is no longer needed to hold the yarn in place:
K.releasehook(carrier);
// ---- single jersey sheet ----
for (let r = 0; r <= rows; r += 1) {
	if (r % 2 === 0) {
		//left-going row:
		for (let n = max; n >= min; n -= 1) {
			K.knit("-", 'f' + n, carrier);
		}
	} else {
		//right-going row:
		for (let n = min; n <= max; n += 1) {
			K.knit("+", 'f' + n, carrier);
		}
	}
}

// ---- take carrier out and drop remaining loops ----
//Take carrier out with yarn inserting hook:
K.outhook(carrier);

//drop loops:
for (let n = min; n <= max; n += 1) {
	K.drop('f' + n);
}

// === Twisted Tucks === 
//Bring in carrier:
K.inhook(carrier);
//Set stitch table entry for cast-on:
K.stitchNumber(101);

//Use a twisted tuck to cast on every stitch.
//Note: this requires a new pass for every stitch, so is pretty slow!
//There are both faster and fancier cast-ons.
//On SWGN2 machines, carriers start on the right, so will start with rightmost needle.
//Miss the rightmost needle to ensure yarn inserting hook is parked to its right instead of left:
K.miss("-", 'f' + max, carrier);
for (let n = max; n >= min; n -= 1) {
	K.tuck("+", 'f' + n, carrier);
}
//Set stitch table entry for knitting:
K.stitchNumber(105);
//knit a plain row to bring the carrier back to the right:
for (let n = min; n <= max; n += 1) {
	K.knit("+", 'f' + n, carrier);
}
//send out yarn inserting hook; it is no longer needed to hold the yarn in place:
K.releasehook(carrier);
// ---- single jersey sheet ----
for (let r = 0; r <= rows; r += 1) {
	if (r % 2 === 0) {
		//left-going row:
		for (let n = max; n >= min; n -= 1) {
			K.knit("-", 'f' + n, carrier);
		}
	} else {
		//right-going row:
		for (let n = min; n <= max; n += 1) {
			K.knit("+", 'f' + n, carrier);
		}
	}
}

// ---- take carrier out and drop remaining loops ----
//Take carrier out with yarn inserting hook:
K.outhook(carrier);

//drop loops:
for (let n = min; n <= max; n += 1) {
	K.drop('f' + n);
}

// === I-Cord === 
//Bring in carrier:
K.inhook(carrier);
//Set stitch table entry for cast-on:
K.stitchNumber(101);

//On SWGN2 machines, carriers start on the right,
//so will start by making a closed tube bind-off for the cord on the right.

//All-needle closed-tube cast-on, with carrier ending on the left:
K.rack(-0.75);
for (let n = max; n >= max - cordWidth; n -= 1) {
	K.tuck("-", 'f' + n, carrier);
	K.tuck("-", 'b' + n, carrier);
}
K.rack(0);

//Set stitch table entry for knitting:
K.stitchNumber(105);

//Knit a small tube, leaving an extra stitch to the right and moving the stitches every course:
//Start first course of the tube:
for (let n = max - cordWidth; n <= max; n += 1) {
	K.knit("+", 'f' + n, carrier);
}
//send out yarn inserting hook; it is no longer needed to hold the yarn in place:
K.releasehook(carrier);
//Middle of tube:
for (let tubeMax = max; tubeMax >= min; tubeMax -= 1) {
	for (let n = tubeMax; n >= tubeMax - cordWidth; n -= 1) {
		K.knit("-", 'b' + n, carrier);
	}
	K.miss("-", 'b' + (tubeMax-cordWidth-1), carrier);
	for (let n = tubeMax - cordWidth; n <= tubeMax; n += 1) {
		K.xfer('f' + n, 'bs' + n);
	}
	K.rack(-1);
	for (let n = tubeMax - cordWidth; n <= tubeMax; n += 1) {
		K.xfer('bs' + n, 'f' + (n-1));
	}
	K.rack(0);
	for (let n = tubeMax - cordWidth; n <= tubeMax; n += 1) {
		K.knit("+", 'f' + (n-1), carrier);
	}
	K.tuck("+", 'f' + tubeMax, carrier);
	for (let n = tubeMax - cordWidth; n <= tubeMax; n += 1) {
		K.xfer('b' + n, 'fs' + n);
	}
	K.rack(1);
	for (let n = tubeMax - cordWidth; n <= tubeMax; n += 1) {
		K.xfer('fs' + n, 'b' + (n-1));
	}
	K.rack(0);
}
//Finish last course of tube (and get carrier to the left):
for (let n = min - 1; n >= min - cordWidth - 1; n -= 1) {
	K.knit("-", 'b' + n, carrier);
}

//Closed bind-off on the tube:
for (let n = min - cordWidth - 1; n <= min - 1; n += 1) {
	K.xfer('b' + n, 'f' + n);
	K.knit("+", 'f' + n, carrier);
	K.rack(-1);
	K.xfer('f' + n, 'b' + (n+1));
	K.knit("+", 'b' + (n+1), carrier);
	K.rack(0);
}
K.xfer('b' + min, 'f' + min);

//Knit regular course to get carrier to the right:
for (let n = min; n <= max; n += 1) {
	K.knit("+", 'f' + n, carrier);
}
// ---- single jersey sheet ----
for (let r = 0; r <= rows; r += 1) {
	if (r % 2 === 0) {
		//left-going row:
		for (let n = max; n >= min; n -= 1) {
			K.knit("-", 'f' + n, carrier);
		}
	} else {
		//right-going row:
		for (let n = min; n <= max; n += 1) {
			K.knit("+", 'f' + n, carrier);
		}
	}
}

// ---- take carrier out and drop remaining loops ----
//Take carrier out with yarn inserting hook:
K.outhook(carrier);

//drop loops:
for (let n = min; n <= max; n += 1) {
	K.drop('f' + n);
}


K.write('cast-on-sampler.swgn2.k');
