package mariaJava;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.IntBinaryOperator;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class Ch3 {
	public void allCh3() {
		System.out.println("chapter 3 lambda expressions");
		validLambdas();
		functionalInterfaces();
		usePredicate();
		
	}
	
	public void validLambdas() {
		System.out.println("Valid lambdas");
		
		// ---- Predicate: ----------
		//---------------------------
		//Boolean expression: 
		//Signature String -> boolean
		Predicate<String> pred = (String list) -> list.isEmpty();
		
		
		//---- Supplier: -----------
		//--------------------------
		//Creating objects: 
		//() -> Apple 
		Supplier<Apple> sup = () -> new Apple(10, "orange");
		
		
		//---- Consumer: ----------
		//-------------------------
		//Consuming from an object:
		//Apple -> void
		Consumer<Apple> con = (Apple apple) -> System.out.println(apple.getWeight());
		
		//Select/Extract from an object:
		//String -> int  ??????!!!!!!!!!!!
		Consumer<String> cons = (String s) -> s.length();
		
		//---- Function: ----------
		//-------------------------
		//Combine two values:
		//int, int -> int
		IntBinaryOperator comb =  (int i1, int i2) -> i1*12;
		IntBinaryOperator comb2 = (int a, int b) -> a*b;
		
		//Previously existing functional interfaces:
		//---- Comparator: -------
		//------------------------
		//Compare two objects:
		//(Apple, Apple)-> int
		Comparator<Apple> c = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
		
	}
	
	void functionalInterfaces() {
		System.out.println("functional interfaces:");
		
		Runnable r1 = () -> System.out.println("Using a lambda");
		
		Runnable r2 = new Runnable() {
			public void run() {
				System.out.println("Using anonymous class");
			}
		};
		
		process(r1);
		process(r2);
		process(() -> System.out.println("with a lambda passed directly"));
		
		try {
			System.out.println("Buffered reader:");
			String oneLine =  processFile((BufferedReader br) -> br.readLine());
			System.out.println("String 1: " + oneLine);
			
			String twoLines = processFile((BufferedReader br2) -> br2.readLine() + br2.readLine());
			System.out.println("String2: " + twoLines);
			
		} catch (Exception e) {
			System.out.println("No file");
		}
	}
	
	public void process(Runnable r) {
		System.out.println("run:");
		r.run();
	}
	
	public String processFile(BufferedReaderProcessor p) throws IOException {
		try (BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\Maria\\Documents\\testingJava8.txt"))) {
			System.out.println("processing file");
			return p.process(br);
		}
		
	}
	
	@FunctionalInterface
	interface BufferedReaderProcessor {
		String process(BufferedReader b) throws IOException;
	}
	
	public void usePredicate() {
//		System.out.println("Predicate");
//		List<String> listStrings = new ArrayList<String>();
//		list
//		
//		
		
	}
}
