/*
 * Copyright 2013 Yuichiro Moriguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.morilib.awk.nano.builtin;

import net.morilib.awk.nano.expr.AwkExpression;
import net.morilib.awk.nano.io.AwkFiles;
import net.morilib.awk.nano.namespace.AwkNamespace;
import net.morilib.awk.nano.value.AwkArray;
import net.morilib.awk.nano.value.AwkInteger;
import net.morilib.awk.nano.value.AwkString;
import net.morilib.awk.nano.value.AwkValue;

/**
 * 組み込み関数splitの記述です。
 *
 *
 * @author MORIGUCHI, Yuichiro 2013/04/13
 */
public class AwkSplit extends AwkExpression {

	private AwkExpression src, dest, delimiter;

	public AwkSplit(AwkExpression src, AwkExpression dest,
			AwkExpression delimiter) {
		this.src = src;
		this.dest = dest;
		this.delimiter = delimiter;
	}

	@Override
	public AwkValue eval(AwkNamespace ns, AwkFiles f) {
		StringBuffer b = null;
		AwkArray r = new AwkArray();
		boolean ws = true;
		String dl = delimiter.eval(ns, f).toString(ns);
		String s  = src.eval(ns, f).toString(ns);
		int c, k = 1;

		for(int i = 0; i < s.length(); i += c > 0xffff ? 2 : 1) {
			c = s.codePointAt(i);
			if(ws && dl.indexOf(c) < 0) {
				b = new StringBuffer().appendCodePoint(c);
				ws = false;
			} else if(!ws && dl.indexOf(c) >= 0) {
				r.putArray(AwkInteger.valueOf(k++).toString(ns),
						AwkString.valueOf(b.toString()));
				b = null;
				ws = true;
			} else if(!ws) {
				b.appendCodePoint(c);
			}
		}

		if(b != null) {
			r.putArray(AwkInteger.valueOf(k).toString(ns),
					AwkString.valueOf(b.toString()));
		}
		dest.assign(ns, r, f);
		return AwkInteger.valueOf(r.size());
	}

}
