/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import net.ranides.assira.text.TextEncoding;

/**
 * Klasa, która rozwiązuje odwieczny problem: z jakim plikiem jest skojarzony
 * podany reader.
 * @author ranides
 */
public class LocalWriter extends Writer {
    
    public static final LocalWriter NULL_WRITER = toStream(NullOutputStream.INSTANCE);
    
    private final File file;
    private final Writer delegate;

    /**
     * Tworzy nowy obiekt powiązany z podaną nazwą pliku oraz readerem.
     * @param file
     * @param delegate
     */
    protected LocalWriter(File file, Writer delegate) {
        this.file = file;
        this.delegate = delegate;
    }
    
    /**
     * Tworzy nowy reader ładujący z podanego pliku tekst w kodowaniu UTF8
     * @param file
     * @return
     * @throws FileNotFoundException
     */
    public static LocalWriter toFile(File file) throws FileNotFoundException {
        return toFile(file, TextEncoding.NIO_UTF8);
    }
    
    /**
     * Tworzy nowy reader ładujący z podanego pliku tekst w podanym jawnie kodowaniu
     * o podanym jawnie kodowaniu
     * @param file
     * @param charset
     * @return
     * @throws FileNotFoundException
     */
    public static LocalWriter toFile(File file, Charset charset) throws FileNotFoundException {
        return new LocalWriter(file, new OutputStreamWriter(new FileOutputStream(file), charset));
    }
    
    /**
     * Tworzy nowy anonimowy reader zawierający podany tekst.
     * @param content
     * @return
     */
    public static LocalWriter toText() {
        return toText(new File("anonymous"));
    }
    
    /**
     * Tworzy nowy reader skojarzony z podaną nazwą pliku zawierający podany tekst.
     * @param path
     * @param content
     * @return
     */
    public static LocalWriter toText(File path) {
        return new LocalWriter(path, new StringWriter());
    }
    
    /**
     * Tworzy nowy anonimowy reader czytający tekst w kodowaniu UTF8 z podanego strumienia
     * @param istream
     * @return
     */
    public static LocalWriter toStream(OutputStream ostream) {
        return toStream(new File("anonymous"), ostream, TextEncoding.NIO_UTF8);
    }
    
    /**
     * Tworzy nowy anonimowy reader czytający tekst w podanym jawnie kodowaniu z podanego strumienia
     * @param istream
     * @param charset
     * @return
     */
    public static LocalWriter toStream(OutputStream ostream, Charset charset) {
        return new LocalWriter(new File("anonymous"), new OutputStreamWriter(ostream, charset));
    }
    
    /**
     * Tworzy nowy reader skojarzony z podaną nazwą pliku, czytający tekst 
     * w kodowaniu UTF8 z podanego strumienia
     * @param path
     * @param istream
     * @return
     */
    public static LocalWriter toStream(File path, OutputStream ostream) {
        return toStream(path, ostream, TextEncoding.NIO_UTF8);
    }
    
    /**
     * Tworzy nowy reader skojarzony z podaną nazwą pliku, czytający tekst 
     * w podanym jawnie kodowaniu z podanego strumienia
     * @param path
     * @param istream
     * @param charset
     * @return
     */
    public static LocalWriter toStream(File path, OutputStream ostream, Charset charset) {
        return new LocalWriter(path, new OutputStreamWriter(ostream, charset));
    }
    
    public static LocalWriter toNull() {
        return NULL_WRITER;
    }

    /**
     * Zwraca nazwę pliku skojarzonego z readerem. Nie musi być to ścieżka 
     * reprezentująca fizyczny plik, z którego została załadowana treść.
     * @return
     */
    public File file() {
        return file;
    }

    @Override
    public void write(int c) throws IOException {
        delegate.write(c);
    }

    @Override
    public void write(char[] cbuf) throws IOException {
        delegate.write(cbuf);
    }

    @Override
    public void write(char[] cbuf, int off, int len) throws IOException {
        delegate.write(cbuf, off, len);
    }

    @Override
    public void write(String str) throws IOException {
        delegate.write(str);
    }

    @Override
    public void write(String str, int off, int len) throws IOException {
        delegate.write(str, off, len);
    }

    @Override
    public Writer append(CharSequence csq) throws IOException {
        return delegate.append(csq);
    }

    @Override
    public Writer append(CharSequence csq, int start, int end) throws IOException {
        return delegate.append(csq, start, end);
    }

    @Override
    public Writer append(char c) throws IOException {
        return delegate.append(c);
    }

    @Override
    public void flush() throws IOException {
        delegate.flush();
    }

    @Override
    public void close() throws IOException {
        delegate.close();
    }
    
    
    
}
