/**
 * 
 */
package org.richfaces.renderer;

import java.util.Iterator;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlOutputText;

import org.ajax4jsf.tests.AbstractAjax4JsfTestCase;
import org.richfaces.component.html.HtmlRichMessages;

import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

/**
 * @author Anton Belevich
 *
 */
public class RichMessagesRendererTest extends AbstractAjax4JsfTestCase {

	HtmlRichMessages messages1 = null;
	HtmlRichMessages messages2 = null;
	
	HtmlInputText input1 = null;
	HtmlInputText input2 = null;
	HtmlInputText input3 = null;
	HtmlInputText input4 = null;
	
	HtmlOutputText output1 = null;
	HtmlOutputText output2 = null;
	HtmlOutputText output3 = null;
	HtmlOutputText output4 = null;
	
	
	public RichMessagesRendererTest(String name) {
		super(name);
	}
	
	public void testRenderStyle() throws Exception {
        HtmlPage page = renderView();
        assertNotNull(page);
        List links = page.getDocumentElement().getHtmlElementsByTagName("link");
        assertNotNull(links);
        HtmlElement link = (HtmlElement)links.get(0);
        assertTrue(link.getAttributeValue("href").contains("org/richfaces/renderkit/html/css/msg.css"));
        
        link = (HtmlElement)links.get(1);
        assertTrue(link.getAttributeValue("href").contains("org/richfaces/renderkit/html/css/msgs.css"));
    }
	
	public void tearDown() throws Exception {
		super.tearDown();
		messages1 = null;
		messages2 = null;
	}
	
	public void setUp() throws Exception {
		
		super.setUp();
		
		input1 = (HtmlInputText)application.createComponent("javax.faces.HtmlInputText");
		input1.setId("input1");
		
		output1 = (HtmlOutputText)application.createComponent("javax.faces.HtmlOutputText");
		output1.setId("output1");
		output1.setValue("output1");
		
		input2 = (HtmlInputText)application.createComponent("javax.faces.HtmlInputText");
		input2.setId("input2");
		
		output2 = (HtmlOutputText)application.createComponent("javax.faces.HtmlOutputText");
		output2.setId("output2");
		output2.setValue("output2");
		
		input3 = (HtmlInputText)application.createComponent("javax.faces.HtmlInputText");
		input3.setId("input3");
		
		output3 = (HtmlOutputText)application.createComponent("javax.faces.HtmlOutputText");
		output3.setId("output3");
		output3.setValue("output3");
		
		input4 = (HtmlInputText)application.createComponent("javax.faces.HtmlInputText");
		input4.setId("input4");
		
		output4 = (HtmlOutputText)application.createComponent("javax.faces.HtmlOutputText");
		output4.setId("output4");
		output4.setValue("output4");
		
		messages1 = (HtmlRichMessages)application.createComponent("org.richfaces.component.RichMessages");
		messages1.setId("message1");
		messages1.setLayout("table");	
		messages1.setErrorClass("errorClass");
		messages1.setWarnClass("warnClass");
		messages1.setFatalClass("fatalClass");
		messages1.setInfoClass("infoClass");
		
		messages1.setErrorLabelClass("errorLabelClass");
		messages1.setWarnLabelClass("errorLabelClass");
		messages1.setFatalLabelClass("errorLabelClass");
		messages1.setInfoLabelClass("errorLabelClass");
		
		messages1.setErrorMarkerClass("errorMarkerClass");
		messages1.setFatalMarkerClass("fatalMarkerClass");
		messages1.setInfoMarkerClass("infoMarkerClass");
		messages1.setWarnMarkerClass("warnMarkerClass");
		
		messages1.getFacets().put("errorMarker", output1);
		messages1.getFacets().put("warnMarker", output2);
		messages1.getFacets().put("fatalMarker", output3);
		messages1.getFacets().put("infoMarker", output4);
		
		messages1.setTitle("TITLE");
		
		messages2 = (HtmlRichMessages)application.createComponent("org.richfaces.component.RichMessages");
		messages2.setId("message2");
		messages2.setLayout("list");
		
		messages2.setErrorClass("errorClass");
		messages2.setWarnClass("warnClass");
		messages2.setFatalClass("fatalClass");
		messages2.setInfoClass("infoClass");
		
		messages2.setErrorLabelClass("errorLabelClass");
		messages2.setWarnLabelClass("errorLabelClass");
		messages2.setFatalLabelClass("errorLabelClass");
		messages2.setInfoLabelClass("errorLabelClass");
		
		messages2.setErrorMarkerClass("errorMarkerClass");
		messages2.setFatalMarkerClass("fatalMarkerClass");
		messages2.setInfoMarkerClass("infoMarkerClass");
		messages2.setWarnMarkerClass("warnMarkerClass");
		
//		messages2.getFacets().put("errorMarker", output1);
//		messages2.getFacets().put("warnMarker", output2);
//		messages2.getFacets().put("fatalMarker", output3);
//		messages2.getFacets().put("infoMarker", output4);
		
		FacesMessage facesMessage = new FacesMessage();
	
		facesMessage.setDetail("TEST detail");
		facesMessage.setSummary("TEST summary");
		facesMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
		facesContext.addMessage("input1",facesMessage);
		
		facesMessage.setDetail("TEST detail");
		facesMessage.setSummary("TEST summary");
		facesMessage.setSeverity(FacesMessage.SEVERITY_FATAL);
		facesContext.addMessage("input2",facesMessage);
		
		facesMessage.setDetail("TEST detail");
		facesMessage.setSummary("TEST summary");
		facesMessage.setSeverity(FacesMessage.SEVERITY_INFO);
		facesContext.addMessage("input3",facesMessage);
		
		facesMessage.setDetail("TEST detail");
		facesMessage.setSummary("TEST summary");
		facesMessage.setSeverity(FacesMessage.SEVERITY_WARN);
		facesContext.addMessage("input4",facesMessage);
				
		facesContext.getViewRoot().getChildren().add(input1);
		facesContext.getViewRoot().getChildren().add(input2);
		facesContext.getViewRoot().getChildren().add(input3);
		facesContext.getViewRoot().getChildren().add(input4);
		facesContext.getViewRoot().getChildren().add(messages1);
		facesContext.getViewRoot().getChildren().add(messages2);
	
	}
	
	public void testRendererMessage() throws Exception{
		HtmlPage page = renderView();
		assertNotNull(page);
		
		HtmlElement table = page.getHtmlElementById(messages1.getClientId(facesContext));
		HtmlElement dl = page.getHtmlElementById(messages2.getClientId(facesContext));
		
		assertNotNull(table);
		assertNotNull(dl);
		
		assertEquals(table.getNodeName().toLowerCase(), "table");
		assertEquals(dl.getNodeName().toLowerCase(), "dl");
		
		String classAttr = table.getAttributeValue("class");
	    assertTrue(classAttr.contains("rich-message"));
	    
		classAttr = dl.getAttributeValue("class");
		assertTrue(classAttr.contains("rich-message"));
		
		// test rendering component mockup for list layout
		Iterator dtIter= dl.getChildElementsIterator();
		for (; dtIter.hasNext();) {
			
			HtmlElement dt = (HtmlElement) dtIter.next();
	    	assertNotNull(dt);
	    	assertEquals(dt.getNodeName().toLowerCase(), "dt");
	    	classAttr = dt.getAttributeValue("class");
			assertTrue(classAttr.contains("errorClass")||classAttr.contains("fatalClass") 
					   ||classAttr.contains("warnClass") ||classAttr.contains("infoClass"));
			
			Iterator spanIter = dt.getChildElementsIterator();
			for (; spanIter.hasNext();) {
				
				HtmlElement span = (HtmlElement) spanIter.next();
		    	assertNotNull(span);
		    	assertEquals(span.getNodeName().toLowerCase(), "span");
		    	
		    	classAttr = span.getAttributeValue("class");
		    	
		    	assertTrue(classAttr.contains("rich-messages-label") || classAttr.contains("rich-messages-marker"));
		    	
		    	assertTrue(classAttr.contains("errorLabelClass") || classAttr.contains("infoLabelClass") 
		    			   || classAttr.contains("fatalLabelClass") || classAttr.contains("warnLabelClass")
		    			   || classAttr.contains("errorMarkerClass") || classAttr.contains("fatalMarkerClass") 
		    			   || classAttr.contains("infoMarkerClass") || classAttr.contains("warnMarkerClass"));
		    	
			}
		}
		
		// test rendering component mockup for table layout
		HtmlElement tbody = (HtmlElement)table.getFirstChild();
		
		assertNotNull(tbody);
		assertEquals(tbody.getNodeName().toLowerCase(), "tbody");
		
		Iterator trIter = tbody.getChildIterator();
	
		for (;trIter.hasNext();) {
		
			HtmlElement tr = (HtmlElement) trIter.next();
			
			assertNotNull(tr);
	    	assertEquals(tr.getNodeName().toLowerCase(), "tr");
	    	
	    	classAttr = tr.getAttributeValue("class");
	    	
			Iterator tdIter = tr.getChildIterator();
			for (;tdIter.hasNext();) {
				
				HtmlElement td = (HtmlElement)tdIter.next();
				assertNotNull(td);
		    	assertEquals(td.getNodeName().toLowerCase(), "td");

		    	String classAttribute = td.getAttributeValue("class");
		    	
				assertTrue(classAttribute.contains("errorClass")|| classAttribute.contains("fatalClass") 
						   || classAttribute.contains("warnClass") || classAttribute.contains("infoClass"));
				
		    	HtmlElement elem = (HtmlElement)td.getFirstChild();
		    	assertNotNull(elem);
		    	
		    	if(elem.getNodeName().equals("span")){
		    		classAttr = elem.getAttributeValue("class");
		    		
		    		assertTrue(classAttr.contains("rich-messages-marker"));
		    		assertTrue(classAttr.contains("errorMarkerClass") || classAttr.contains("fatalMarkerClass") 
			    			   || classAttr.contains("infoMarkerClass") || classAttr.contains("warnMarkerClass"));
		    	}

		    	DomNode node = elem.getNextSibling();
		    	while (!(node instanceof HtmlElement)) {
		    		node = node.getNextSibling();
		    	}
		    	
		    	HtmlElement label = (HtmlElement) node;
		    	if(label.getNodeName().equals("span")){
		    		classAttr = label.getAttributeValue("class");
		    		
		    		assertTrue(classAttr.contains("rich-messages-label"));
			    	assertTrue(classAttr.contains("errorLabelClass") || classAttr.contains("infoLabelClass") 
			    			   || classAttr.contains("fatalLabelClass") || classAttr.contains("warnLabelClass"));
			    
		    	}
			}
		}
	}
}
