/*
 *    DisplayItemUtil.java
 *    Copyright (C) 2016 New Zealand Digital Library, http://www.nzdl.org
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package org.greenstone.gsdl3.util;

import org.apache.log4j.Logger;

import org.greenstone.gsdl3.util.Dictionary;
import org.greenstone.gsdl3.util.GSXML;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/** various methods for handling displayItems and choosing the right one for the specified language */

public class DisplayItemUtil
{

  static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.DisplayItemUtil.class.getName());

  public static Element createDisplayItem(Document doc, String name, String lang, String value) {

    Element di = doc.createElement(GSXML.DISPLAY_TEXT_ELEM);
    di.setAttribute(GSXML.NAME_ATT, name);
    di.setAttribute(GSXML.LANG_ATT, lang);
    GSXML.setNodeText(di, value);
    return di;
  }
  /** looks for displayItems from config element and stores them in displayItemList in the form
   
      <displayItem name="X">
        <displayItem name="X" lang="">value</displayItem>
        <displayItem name="X" lang="">value</displayItem>
      </displayItem>

   */
  public static boolean storeDisplayItems(Element display_item_list, Element config) {
    if (config == null) {
      logger.error("the config element is null, no displayItems to be found");
      return false;
    }
    Document doc = display_item_list.getOwnerDocument();
    NodeList displaynodes = config.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
    int num_nodes = displaynodes.getLength();
    if (num_nodes > 0) {
      
	for (int k = 0; k < num_nodes; k++) {
	Element d = (Element) displaynodes.item(k);
	String name = d.getAttribute(GSXML.NAME_ATT);
	Element this_item = GSXML.getNamedElement(display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.NAME_ATT, name);
	if (this_item == null) {
	  this_item = doc.createElement(GSXML.DISPLAY_TEXT_ELEM);
	  this_item.setAttribute(GSXML.NAME_ATT, name);
	  display_item_list.appendChild(this_item);
	}
	
	this_item.appendChild(doc.importNode(d, true));
      }
    }
    
    return true;
     
  }
  
    /** Choose the best displayItem from a list - that matches lang - and return a copy of it created by doc. */
    public static Element chooseBestMatchDisplayItem(Document doc, Element display_item_list, String lang, String default_lang, ClassLoader class_loader) {
	if (display_item_list == null) {
	    return null;
	}

	// is there one with the specified language?
	Element best_di = GSXML.getNamedElement(display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, lang);
	if (best_di != null) {
	    return (Element)doc.importNode(best_di, true);
	}

	// if not, have we got one with a key?
	best_di = GSXML.getNamedElement(display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.KEY_ATT, null);
	if (best_di != null) {
	    // look up the dictionary
          String value = Dictionary.createDictionaryAndGetString(best_di.getAttribute(GSXML.DICTIONARY_ATT), class_loader, best_di.getAttribute(GSXML.KEY_ATT), lang, null);
	    if (value != null) {
		// copy the node now. Don't want to be modifying the underlying list as can lead to concurrent access problems.
		Element new_di = (Element)doc.importNode(best_di, true);
		GSXML.setNodeText(new_di, value);
		return new_di;
	    }
	}
	// ok, key one didn't work, can we use default lang?
	if (lang != default_lang) {
	  best_di = GSXML.getNamedElement(display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, default_lang);
	  if (best_di != null) {
	    return (Element)doc.importNode(best_di, true);
	  }
	}
	// STILL haven't found one, lets use the first one with a lang att (so we don't just get the key one back
	best_di = (Element) GSXML.getNamedElement(display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, null);
	if (best_di != null) {
	    return (Element)doc.importNode(best_di, true);
	}
	return null;

    }

  /** Finds the best language specific match for each displayItem in display_item_list and adds it to description */
  public static boolean addLanguageSpecificDisplayItems(Element description, Element display_item_list, String lang, String default_lang, ClassLoader class_loader) {

    Document doc = description.getOwnerDocument();
    NodeList items = display_item_list.getChildNodes();
    
    for (int i = 0; i < items.getLength(); i++)
      { // for each key
	Element di_list = (Element) items.item(i);
	// takes a copy of the best matching item
	Element new_m = chooseBestMatchDisplayItem(doc, di_list, lang, default_lang, class_loader);

	if (new_m != null) {
	  description.appendChild(new_m);
	}
      } // for each key
    return true;
    
  }


}
