/*
 * citygml4j - The Open Source Java API for CityGML
 * https://github.com/citygml4j
 *
 * Copyright 2013-2020 Claus Nagel <claus.nagel@gmail.com>
 *
 * 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 org.citygml4j.builder.cityjson.json.io.writer;

import com.google.gson.stream.JsonWriter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;

public class CityJSONOutputFactory {
	boolean removeDuplicateChildGeometries;
	boolean generateCityGMLMetadata;

	public CityJSONWriter createCityJSONWriter(File file) throws CityJSONWriteException {
		try {
			createParentDirectories(file.toPath());
			return new CityJSONWriter(new JsonWriter(new BufferedWriter(new FileWriter(file))), this);
		} catch (IOException e) {
			throw new CityJSONWriteException("Caused by: ", e);
		}
	}

	public CityJSONWriter createCityJSONWriter(File file, String encoding) throws CityJSONWriteException {
		try {
			createParentDirectories(file.toPath());
			return new CityJSONWriter(new JsonWriter(new OutputStreamWriter(new FileOutputStream(file), encoding)), this);
		} catch (IOException e) {
			throw new CityJSONWriteException("Caused by: ", e);
		}
	}

	public CityJSONWriter createCityJSONWriter(OutputStream outputStream) {
		return new CityJSONWriter(new JsonWriter(new OutputStreamWriter(outputStream)), this);
	}

	public CityJSONWriter createCityJSONWriter(OutputStream outputStream, String encoding) throws CityJSONWriteException {
		try {
			return new CityJSONWriter(new JsonWriter(new OutputStreamWriter(outputStream, encoding)), this);
		} catch (UnsupportedEncodingException e) {
			throw new CityJSONWriteException("Caused by: ", e);
		}
	}
	
	public CityJSONWriter createCityJSONWriter(Writer writer) {
		return new CityJSONWriter(new JsonWriter(writer), this);
	}

	public CityJSONChunkWriter createCityJSONChunkWriter(File file) throws CityJSONWriteException {
		try {
			createParentDirectories(file.toPath());
			return new CityJSONChunkWriter(new JsonWriter(new BufferedWriter(new FileWriter(file))), this);
		} catch (IOException e) {
			throw new CityJSONWriteException("Caused by: ", e);
		}
	}

	public CityJSONChunkWriter createCityJSONChunkWriter(File file, String encoding) throws CityJSONWriteException {
		try {
			createParentDirectories(file.toPath());
			return new CityJSONChunkWriter(new JsonWriter(new OutputStreamWriter(new FileOutputStream(file), encoding)), this);
		} catch (IOException e) {
			throw new CityJSONWriteException("Caused by: ", e);
		}
	}

	public CityJSONChunkWriter createCityJSONChunkWriter(OutputStream outputStream) {
		return new CityJSONChunkWriter(new JsonWriter(new OutputStreamWriter(outputStream)), this);
	}

	public CityJSONChunkWriter createCityJSONChunkWriter(OutputStream outputStream, String encoding) throws CityJSONWriteException {
		try {
			return new CityJSONChunkWriter(new JsonWriter(new OutputStreamWriter(outputStream, encoding)), this);
		} catch (UnsupportedEncodingException e) {
			throw new CityJSONWriteException("Caused by: ", e);
		}
	}
	
	public CityJSONChunkWriter createCityJSONChunkWriter(Writer writer) {
		return new CityJSONChunkWriter(new JsonWriter(writer), this);
	}

	public boolean isRemoveDuplicateChildGeometries() {
		return removeDuplicateChildGeometries;
	}

	public void setRemoveDuplicateChildGeometries(boolean removeDuplicateChildGeometries) {
		this.removeDuplicateChildGeometries = removeDuplicateChildGeometries;
	}

	public boolean isGenerateCityGMLMetadata() {
		return generateCityGMLMetadata;
	}

	public void setGenerateCityGMLMetadata(boolean generateCityGMLMetadata) {
		this.generateCityGMLMetadata = generateCityGMLMetadata;
	}

	private void createParentDirectories(Path path) throws IOException {
		Path parent = path.getParent();
		if (parent != null && !Files.exists(parent))
			Files.createDirectories(parent);
	}
	
}

@@ -1762,32 +1762,51 @@
  JsonWriter(new 
+BufferedWriter(new 
 OutputStreamWrit
@@ -1838,32 +1838,33 @@
 ile), encoding))
+)
 , this);%0A%09%09%7D cat
@@ -2059,32 +2059,51 @@
  JsonWriter(new 
+BufferedWriter(new 
 OutputStreamWrit
@@ -2111,32 +2111,33 @@
 r(outputStream))
+)
 , this);%0A%09%7D%0A%0A%09pu
@@ -2301,32 +2301,51 @@
  JsonWriter(new 
+BufferedWriter(new 
 OutputStreamWrit
@@ -2363,32 +2363,33 @@
 ream, encoding))
+)
 , this);%0A%09%09%7D cat
@@ -3162,32 +3162,51 @@
  JsonWriter(new 
+BufferedWriter(new 
 OutputStreamWrit
@@ -3238,32 +3238,33 @@
 ile), encoding))
+)
 , this);%0A%09%09%7D cat
@@ -3474,32 +3474,51 @@
  JsonWriter(new 
+BufferedWriter(new 
 OutputStreamWrit
@@ -3534,16 +3534,17 @@
 Stream))
+)
 , this);
@@ -3731,32 +3731,51 @@
  JsonWriter(new 
+BufferedWriter(new 
 OutputStreamWrit
@@ -3801,16 +3801,17 @@
 coding))
+)
 , this);

use buffered writers for CityJSON per default