/*
 * Zorbage: an algebraic data hierarchy for use in numeric processing.
 *
 * Copyright (C) 2016-2020 Barry DeZonia
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package nom.bdezonia.zorbage.type.character;


import nom.bdezonia.zorbage.algebra.*;
import nom.bdezonia.zorbage.storage.coder.CharCoder;
import nom.bdezonia.zorbage.misc.Hasher;

/**
 * 
 * @author Barry DeZonia
 *
 */
public final class FixedStringMember
	implements
		CharCoder, Allocatable<FixedStringMember>, Duplicatable<FixedStringMember>,
		Settable<FixedStringMember>, Gettable<FixedStringMember>
{
	private final int maxLen;
	private String v;
	
	public FixedStringMember(int len) {
		maxLen = len;
		v = "";
	}

	public FixedStringMember() {
		this(0);
	}
	
	public FixedStringMember(String value) {
		maxLen = value.length();
		v = value;
	}
	
	public FixedStringMember(FixedStringMember value) {
		maxLen = value.maxLen;
		v = value.v;
	}
	
	public String v() {
		return chars(v);
	}
	
	public void setV(String val) {
		if (maxLen < val.length()) {
			v = val.substring(0, maxLen);
		}
		else {
			v = val;
		}
	}
	
	@Override
	public void set(FixedStringMember other) {
		setV(other.v());
	}
	
	@Override
	public void get(FixedStringMember other) {
		other.setV(v());
	}

	@Override
	public String toString() {
		return chars(v);
	}

	@Override
	public int charCount() {
		return maxLen;
	}

	@Override
	public void fromCharArray(char[] arr, int index) {
		StringBuilder b = new StringBuilder();
		for (int i = 0; i < maxLen; i++) {
			b.append(arr[index+i]);
		}
		v = b.toString();
	}

	@Override
	public void toCharArray(char[] arr, int index) {
		String chs = chars(v);
		for (int i = 0; i < chs.length(); i++) {
			arr[index+i] = chs.charAt(i);
		}
		for (int i = chs.length(); i < maxLen; i++) {
			arr[index+i] = 0;
		}
	}

	@Override
	public FixedStringMember allocate() {
		return new FixedStringMember(maxLen);
	}

	@Override
	public FixedStringMember duplicate() {
		return new FixedStringMember(this);
	}

	public void getV(FixedStringMember value) {
		get(value);
	}

	public void setV(FixedStringMember value) {
		set(value);
	}

	@Override
	public int hashCode() {
		int v = 1;
		v = Hasher.PRIME * v + Hasher.hashCode(chars(this.v));
		return v;
	}
	
	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o instanceof FixedStringMember) {
			return G.FSTRING.isEqual().call(this, (FixedStringMember) o);
		}
		return false;
	}
	
	private String chars(String value) {
		StringBuilder b = new StringBuilder();
		int len = value.length();
		for (int i = 0; i < len; i++) {
			char ch = value.charAt(i);
			if (ch == 0)
				return b.toString();
			else
				b.append(ch);
		}
		return b.toString();
	}
}

@@ -1552,20 +1552,19 @@
 e.coder.
-Char
+Int
 Coder;%0Ai
@@ -1695,20 +1695,19 @@
 ments%0A%09%09
-Char
+Int
 Coder, A
@@ -1840,22 +1840,16 @@
 private 
-final 
 int maxL
@@ -2588,20 +2588,19 @@
 lic int 
-char
+int
 Count() 
@@ -2616,16 +2616,20 @@
 n maxLen
+ + 1
 ;%0A%09%7D%0A%0A%09@
@@ -2654,30 +2654,28 @@
 oid from
-Char
+Int
 Array(
-char
+int
 %5B%5D arr, 
@@ -2679,32 +2679,55 @@
 r, int index) %7B%0A
+%09%09maxLen = arr%5Bindex%5D;%0A
 %09%09StringBuilder 
@@ -2788,16 +2788,45 @@
  i++) %7B%0A
+%09%09%09if (arr%5Bindex+1+i%5D != 0)%0A%09
 %09%09%09b.app
@@ -2829,16 +2829,23 @@
 .append(
+(char) 
 arr%5Binde
@@ -2846,16 +2846,18 @@
 r%5Bindex+
+1+
 i%5D);%0A%09%09%7D
@@ -2911,22 +2911,20 @@
 d to
-Char
+Int
 Array(
-char
+int
 %5B%5D a
@@ -2936,24 +2936,47 @@
 nt index) %7B%0A
+%09%09arr%5Bindex%5D = maxLen;%0A
 %09%09String chs
@@ -3022,16 +3022,30 @@
 length()
+ && i %3C maxLen
 ; i++) %7B
@@ -3054,24 +3054,26 @@
 %09%09arr%5Bindex+
+1+
 i%5D = chs.cha
@@ -3145,16 +3145,18 @@
 r%5Bindex+
+1+
 i%5D = 0;%0A

Make fixed len strings use IntCoder for now