/*
 * @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.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;
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 LocalReader extends Reader {
    
    private final File file;
    private final Reader delegate;

    /**
     * Tworzy nowy obiekt powiązany z podaną nazwą pliku oraz readerem.
     * @param file
     * @param delegate
     */
    protected LocalReader(File file, Reader 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 LocalReader fromFile(File file) throws FileNotFoundException {
        return fromFile(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 LocalReader fromFile(File file, Charset charset) throws FileNotFoundException {
        return new LocalReader(file, new InputStreamReader(new FileInputStream(file), charset));
    }
    
    /**
     * Tworzy nowy anonimowy reader zawierający podany tekst.
     * @param content
     * @return
     */
    public static LocalReader fromText(String content) {
        return fromText(new File("anonymous"), content);
    }
    
    /**
     * Tworzy nowy reader skojarzony z podaną nazwą pliku zawierający podany tekst.
     * @param path
     * @param content
     * @return
     */
    public static LocalReader fromText(File path, String content) {
        return new LocalReader(path, new StringReader(content));
    }
    
    /**
     * Tworzy nowy anonimowy reader czytający tekst w kodowaniu UTF8 z podanego strumienia
     * @param istream
     * @return
     */
    public static LocalReader fromStream(InputStream istream) {
        return fromStream(new File("anonymous"), istream, TextEncoding.NIO_UTF8);
    }
    
    /**
     * Tworzy nowy anonimowy reader czytający tekst w podanym jawnie kodowaniu z podanego strumienia
     * @param istream
     * @param charset
     * @return
     */
    public static LocalReader fromStream(InputStream istream, Charset charset) {
        return new LocalReader(new File("anonymous"), new InputStreamReader(istream, 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 LocalReader fromStream(File path, InputStream istream) {
        return fromStream(path, istream, 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 LocalReader fromStream(File path, InputStream istream, Charset charset) {
        return new LocalReader(path, new InputStreamReader(istream, charset));
    }

    /**
     * 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 int read(CharBuffer target) throws IOException {
        return delegate.read(target);
    }

    @Override
    public int read() throws IOException {
        return delegate.read();
    }

    @Override
    public int read(char[] cbuf) throws IOException {
        return delegate.read(cbuf);
    }

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

    @Override
    public long skip(long n) throws IOException {
        return delegate.skip(n);
    }

    @Override
    public boolean ready() throws IOException {
        return delegate.ready();
    }

    @Override
    public boolean markSupported() {
        return delegate.markSupported();
    }

    @Override
    public void mark(int readAheadLimit) throws IOException {
        delegate.mark(readAheadLimit);
    }

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

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