package innovimax.mixthem.operation;

import innovimax.mixthem.MixException;
import innovimax.mixthem.arguments.ParamValue;
import innovimax.mixthem.arguments.RuleParam;
import innovimax.mixthem.arguments.TokenType;

import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.IntStream;

/**
* <p>Zips two or more characters.</p>
* <p>Zipping stops when a character is missing.</p>
* @see CharOperation
* @author Innovimax
* @version 1.0
*/
public class DefaultCharZipping extends AbstractCharOperation {
	
	private final String sep;

	/**
	* Constructor
	* @param selection The file index selection (maybe empty)
 	* @param params The list of parameters (maybe empty)
	* @see innovimax.mixthem.arguments.RuleParam
	* @see innovimax.mixthem.arguments.ParamValue
	*/
	public DefaultCharZipping(final Set<Integer> selection, final TokenType tokenType, final Map<RuleParam, ParamValue> params) {
		super(selection, tokenType, params);		
		this.sep = params.getOrDefault(RuleParam.ZIP_SEP, ZipOperation.DEFAULT_ZIP_SEPARATOR.getValue()).asString();
	}
	
	@Override
	public void process(final int[] charRange, final CharResult result) throws MixException {
		//System.out.println("RANGE="+Arrays.toString(charRange));	
		if (IntStream.range(0, charRange.length).allMatch(index -> charRange[index] != -1)) {			
			final int len = charRange.length + (charRange.length - 1) * sep.length();
			final int[] array = new int[len];
			int index = 0;
			for (int i=0; i < charRange.length; i++) {
				array[index++] = charRange[i];				
				if (index < array.length) {
        				for (int j = 0; j < sep.length(); j++) {
						array[index++] = (int) sep.charAt(j);
					}				
				}
			}
			result.setResult(Arrays.stream(array));
		}
	}
	
}

@@ -213,32 +213,170 @@
 pe;%0A
-%0Aimport java.util.Arrays
+import innovimax.mixthem.io.IToken;%0Aimport innovimax.mixthem.io.ITokenRange;%0Aimport innovimax.mixthem.io.Token;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List
 ;%0Aim
@@ -658,53 +658,24 @@
 ract
-CharOperation %7B%0A%09%0A%09private final String sep;%0A
+TokenZipping %7B%0A%09
 %0A%09/*
@@ -1071,121 +1071,8 @@
 ms);
-%09%09%0A%09%09this.sep = params.getOrDefault(RuleParam.ZIP_SEP, ZipOperation.DEFAULT_ZIP_SEPARATOR.getValue()).asString();
 %0A%09%7D%0A
@@ -1115,18 +1115,25 @@
 nal 
-int%5B%5D char
+ITokenRange token
 Rang
@@ -1141,20 +1141,22 @@
 , final 
-Char
+IToken
 Result r
@@ -1220,44 +1220,89 @@
 E=%22+
-Arrays.toString(charRange)
+tokenRange.toString());%0A%09%09final List%3CIToken%3E tokens = new ArrayList%3CIToken%3E(
 );
-%09
 %0A%09%09
-if (
 IntS
@@ -1320,441 +1320,329 @@
 (0, 
-char
+token
 Range.
-length).allMatch(index -%3E charRange%5Bindex%5D != -1)) %7B%09%09%09%0A%09%09%09final int len = charRange.length + (charRange.length - 1) * sep.length();%0A%09%09%09final int%5B%5D array = new int%5Blen%5D;%0A%09%09%09int index = 0;%0A%09%09%09for (int i=0; i %3C charRange.length; i++) %7B%0A%09%09%09%09array%5Bindex++%5D = charRange%5Bi%5D;
+size()).forEach(channel -%3E %7B%0A%09%09%09if (channel %3E 0) %7B%0A%09%09%09%09IntStream.range(0, this.sep.length()).forEach(index -%3E %7B%0A%09%09%09%09%09tokens.add(Token.createCharToken((int) this.sep.charAt(index)));%0A
 %09%09%09%09
+%7D);
 %0A%09%09%09
-%09if (index %3C array.length) %7B%0A        %09%09%09%09for (int j = 0; j %3C sep.length(); j++) %7B%0A%09%09%09%09%09%09array%5Bindex++%5D = (int) sep.charAt(j);%0A%09%09%09%09%09%7D%09%09%09%09%0A%09%09
+%7D%0A%09%09%09tokens.add(Token.createCharToken(tokenRange.getToken(channel).asCharacter()));%0A%0A
 %09%09%7D
+);
 %0A%09%09
-%09%7D
+if (tokens.size() %3E 0) %7B
 %0A%09%09%09
@@ -1662,28 +1662,14 @@
 ult(
-Arrays.stream(array)
+tokens
 );%0A%09

Update char zipping op using tokens