/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//	レイアウトカスタマイズ画面アクションクラス
//
//		変更履歴
//			2005.02.19  新規作成  村上 靖征
//
//	機能
//
//	このクラスはレイアウトカスタマイズ画面のアクションクラスです。
//
////////////////////////////////////////////////////////////////

package jp.co.ntt.lms.xmf.actions;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import jp.co.ntt.lms.xmf.CustomLayoutManager;
import jp.co.ntt.lms.xmf.FrameLayout;
import jp.co.ntt.lms.xmf.LayoutElement;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 *  レイアウトカスタマイズ画面アクションクラス
 * 
 *  このクラスはレイアウトカスタマイズ画面のアクションクラスです。
 * 
 *  @author 村上 靖征
 *  @version 1.0
 */
public class CustomizeLayoutAction extends Action
{
				
	/*
	 * execute のオーバーライド実装
	 *
	 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		String action = request.getParameter("action");

		String topVisibility = request.getParameter("topvisibility");
		if (topVisibility == null)
		{
			topVisibility = "true";
		}
		String leftVisibility = request.getParameter("leftvisibility");
		if (leftVisibility == null)
		{
			leftVisibility = "true";
		}
		
		if (action == null)
		{
			loadDefault(request);
		}
		else
		{
			if (action.equals("move-to-top"))
			{
				String target = request.getParameter("target");
				String from = request.getParameter("from");
				
				String[] currentTop = getCurrent("top", request);
				String[] currentFrom = getCurrent(from, request);
				
				String[] removed = removeFromArray(currentFrom, new String[]{target});
				String[] appended = appendToArray(currentTop, new String[]{target});
				
				setCurrent("top", appended, request);
				setCurrent(from, removed, request);
				setCurrentOther(new String[]{"top", from}, request);
				
				topVisibility = "true";
			}
			if (action.equals("move-to-left"))
			{
				String target = request.getParameter("target");
				String from = request.getParameter("from");
				
				String[] currentLeft = getCurrent("left", request);
				String[] currentFrom = getCurrent(from, request);
				
				String[] removed = removeFromArray(currentFrom, new String[]{target});
				String[] appended = appendToArray(currentLeft, new String[]{target});
				
				setCurrent("left", appended, request);
				setCurrent(from, removed, request);
				setCurrentOther(new String[]{"left", from}, request);
				
				leftVisibility = "true";
			}
			if (action.equals("move-to-content"))
			{
			}
			if (action.equals("remove"))
			{
				String target = request.getParameter("target");
				String from = request.getParameter("from");
				
				String[] currentNoAssign = getCurrent("noassign", request);
				String[] currentFrom = getCurrent(from, request);
				
				String[] removed = removeFromArray(currentFrom, new String[]{target});
				String[] appended = appendToArray(currentNoAssign, new String[]{target});
				
				setCurrent("noassign", appended, request);
				setCurrent(from, removed, request);
				setCurrentOther(new String[]{"noassign", from}, request);
			}
			if (action.equals("top-visibility-true"))
			{
				topVisibility = "true";
				setCurrent("top", getCurrent("top", request), request);
				setCurrent("left", getCurrent("left", request), request);
				setCurrent("content", getCurrent("content", request), request);
				setCurrent("noassign", getCurrent("noassign", request), request);
			}
			if (action.equals("top-visibility-false"))
			{
				if (topVisibility.equals("true"))
				{
					String[] currentTop = getCurrent("top", request);
					String[] currentNoAssign = getCurrent("noassign", request);
					String[] removed = removeFromArray(currentTop, currentTop);
					String[] appended = appendToArray(currentNoAssign, currentTop);

					setCurrent("top", removed, request);
					setCurrent("noassign", appended, request);
					setCurrentOther(new String[]{"top", "noassign"}, request);

					topVisibility = "false";
				}
			}
			if (action.equals("left-visibility-true"))
			{
				leftVisibility = "true";
				setCurrent("top", getCurrent("top", request), request);
				setCurrent("left", getCurrent("left", request), request);
				setCurrent("content", getCurrent("content", request), request);
				setCurrent("noassign", getCurrent("noassign", request), request);
			}
			if (action.equals("left-visibility-false"))
			{
				if (leftVisibility.equals("true"))
				{
					String[] currentLeft = getCurrent("left", request);
					String[] currentNoAssign = getCurrent("noassign", request);
					String[] removed = removeFromArray(currentLeft, currentLeft);
					String[] appended = appendToArray(currentNoAssign, currentLeft);

					setCurrent("left", removed, request);
					setCurrent("noassign", appended, request);
					setCurrentOther(new String[]{"left", "noassign"}, request);

					leftVisibility = "false";
				}
			}
			if (action.equals("save"))
			{
				try
				{
					saveDefault(request, topVisibility, leftVisibility);
					setStatus(request, "1");
				}
				catch(Exception e)
				{
					setStatus(request, "2");
				}
				loadDefault(request);
			}
			setVisibility(topVisibility, leftVisibility, request);
		}
		return mapping.findForward("view");
	}
	
	private void setStatus(HttpServletRequest request, String status)
	{
		request.setAttribute("status", status);
	}
	
	private void setTopVisibility(HttpServletRequest request, String topVisibility)
	{
		request.setAttribute("topvisibility", topVisibility);
	}
	
	private void setLeftVisibility(HttpServletRequest request, String leftVisibility)
	{
		request.setAttribute("leftvisibility", leftVisibility);
	}
	
	private void setVisibility(String topVisibility, String leftVisibility, HttpServletRequest request)
	{
		setTopVisibility(request, topVisibility);
		setLeftVisibility(request, leftVisibility);
	}
	
	private void loadDefault(HttpServletRequest request)
	{
		CustomLayoutManager layoutManager = new CustomLayoutManager();
		layoutManager.loadDefaultDef(getServlet().getServletContext());
		
		ArrayList topKeys = new ArrayList();
		if (layoutManager.isTopFrameVisible())
		{
			FrameLayout topFrame = layoutManager.getTopFrame();
			LayoutElement[] topFrameElements = topFrame.getElements();
			for (int i=0; i < topFrameElements.length; i++)
			{
				topKeys.add(topFrameElements[i].getName());
			}
			setTopVisibility(request, "true");
		}
		else
		{
			setTopVisibility(request, "false");
		}
		setCurrent("top", (String[])topKeys.toArray(new String[]{}), request);
		
		ArrayList leftKeys = new ArrayList();
		if (layoutManager.isLeftFrameVisible())
		{
			FrameLayout leftFrame = layoutManager.getLeftFrame();
			LayoutElement[] leftFrameElements = leftFrame.getElements();
			for (int i=0; i < leftFrameElements.length; i++)
			{
				leftKeys.add(leftFrameElements[i].getName());
			}
			setLeftVisibility(request, "true");
		}
		else
		{
			setLeftVisibility(request, "false");
		}
		setCurrent("left", (String[])leftKeys.toArray(new String[]{}), request);
		
		// 2005.03.21 Modified by N.Umehara
		String[] topleftKeys = new String[]{"logo", "user_info", "system_menu", "main_menu", "tree_view", "view_menu"};
		String[] noassignKeys = removeFromArray(topleftKeys, (String[])topKeys.toArray(new String[]{}));
		noassignKeys = removeFromArray(noassignKeys, (String[])leftKeys.toArray(new String[]{}));
		
		// 2005.03.21 Modified by N.Umehara
		setCurrent("content", new String[]{"name_path", "changetype_tab", "groupuser_list", "groupuser_info", "locontainer_list", "locontainer_info", "methodstudy_todo"}, request);
		setCurrent("noassign", noassignKeys, request);
	}
	
	private String getResource(String name)
	{
		if (name.equals("logo"))
		{
			return "/view/xmo/Base/parts/Logo.vm";
		}
		if (name.equals("user_info"))
		{
			return "/view/xmo/Base/parts/UserInfo.vm";
		}
		if (name.equals("main_menu"))
		{
			return "/view/xmo/Base/parts/MainMenu.vm";
		}
		if (name.equals("system_menu"))
		{
			return "/view/xmo/Base/parts/SystemMenu.vm";
		}
		if (name.equals("tree_view"))
		{
			return "/view/xmo/Base/parts/TreeView.vm";
		}
		if (name.equals("name_path"))
		{
			return "/view/xmo/Base/parts/NamePath.vm";
		}
		if (name.equals("changetype_tab"))
		{
			return "/view/xmo/Base/parts/ChangeTypeTab.vm";
		}
		if (name.equals("groupuser_info"))
		{
			return "/view/xmo/Base/parts/GroupUserInfo.vm";
		}
		if (name.equals("groupuser_list"))
		{
			return "/view/xmo/Base/parts/GroupUserList.vm";
		}
		if (name.equals("locontainer_info"))
		{
			return "/view/xmo/Base/parts/LoContainerInfo.vm";
		}
		if (name.equals("locontainer_list"))
		{
			return "/view/xmo/Base/parts/LoContainerList.vm";
		}
		if (name.equals("view_menu"))
		{
			return "/view/method/parts/ViewMenu.vm";
		}
		if (name.equals("methodstudy_todo"))
		{
			return "/view/method/parts/MethodStudyToDo.vm";
		}
		return "";
	}
	
	private void saveDefault(HttpServletRequest request, String topVisibility, String leftVisibility) throws Exception
	{
		String[] currentTop = getCurrent("top", request);
		String[] currentLeft = getCurrent("left", request);
		String[] currentContent = getCurrent("content", request);

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		DOMImplementation domImpl=builder.getDOMImplementation();
		Document document = domImpl.createDocument("", "layout", null);
		Element root = document.getDocumentElement();
		
		if (topVisibility.equals("true"))
		{
			Element topFrame = document.createElement("frame");
			topFrame.setAttribute("name", "top");
			for (int i=0; i < currentTop.length; i++)
			{
				Element component = document.createElement("component");
				component.setAttribute("name", currentTop[i]);
				component.setAttribute("resource", getResource(currentTop[i]));
				topFrame.appendChild(component);
			}
			root.appendChild(topFrame);
		}

		if (leftVisibility.equals("true"))
		{
			Element leftFrame = document.createElement("frame");
			leftFrame.setAttribute("name", "left");
			for (int i=0; i < currentLeft.length; i++)
			{
				Element component = document.createElement("component");
				component.setAttribute("name", currentLeft[i]);
				component.setAttribute("resource", getResource(currentLeft[i]));
				leftFrame.appendChild(component);
			}
			root.appendChild(leftFrame);
		}

		Element contentFrame = document.createElement("frame");
		contentFrame.setAttribute("name", "content");
		for (int i=0; i < currentContent.length; i++)
		{
			Element component = document.createElement("component");
			component.setAttribute("name", currentContent[i]);
			component.setAttribute("resource", getResource(currentContent[i]));
			contentFrame.appendChild(component);
		}
		root.appendChild(contentFrame);
		
		CustomLayoutManager layoutManager = new CustomLayoutManager();
		layoutManager.saveDefaultDef(getServlet().getServletContext(), document);
	}
	
	private String join(String[] target)
	{
		String result = "";
		for (int i=0; i < target.length; i++)
		{
			if (result.length() != 0)
			{
				result += ("/" + target[i]);
			}
			else
			{
				result += target[i];
			}
		}
		return result;
	}
	
	private String[] split(String target, String regex)
	{
		if (target == null)
		{
			return new String[]{};
		}
		else
		{
			if (target.length() == 0)
			{
				return new String[]{};
			}
			else
			{
				return target.split(regex);
			}
		}
	}
	
	private String[] appendToArray(String[] target, String[] items)
	{
		String result = "";
		
		result = join(target);
		
		for (int i=0; i < items.length; i++)
		{
			if (result.length() != 0)
			{
				result += ("/" + items[i]);
			}
			else
			{
				result += items[i];
			}
		}
		return split(result, "/");
	}
	
	private String[] removeFromArray(String[] target, String[] items)
	{
		String result = "";
		for (int i=0; i < target.length; i++)
		{
			boolean match = false;
			for (int j=0; j < items.length; j++)
			{
				if (target[i].equals(items[j]))
				{
					match = true;
					break;
				}
			}
			if (!match)
			{
				if (result.length() != 0)
				{
					result += ("/" + target[i]);
				}
				else
				{
					result += target[i];
				}
			}
		}
		return split(result, "/");
	}
	
	private String[] getCurrentTop(HttpServletRequest request)
	{
		return split(request.getParameter("top"), "/");
	}
	
	private void setCurrentTop(String[] current, HttpServletRequest request)
	{
		request.setAttribute("top", join(current));
	}
	
	private String[] getCurrentLeft(HttpServletRequest request)
	{
		return split(request.getParameter("left"), "/");
	}

	private void setCurrentLeft(String[] current, HttpServletRequest request)
	{
		request.setAttribute("left", join(current));
	}

	private String[] getCurrentContent(HttpServletRequest request)
	{
		return split(request.getParameter("content"), "/");
	}

	private void setCurrentContent(String[] current, HttpServletRequest request)
	{
		request.setAttribute("content", join(current));
	}

	private String[] getCurrentNoAssign(HttpServletRequest request)
	{
		return split(request.getParameter("noassign"), "/");
	}
	
	private void setCurrentNoAssign(String[] current, HttpServletRequest request)
	{
		request.setAttribute("noassign", join(current));
	}

	private String[] getCurrent(String key, HttpServletRequest request)
	{
		if (key.equals("top"))
		{
			return getCurrentTop(request);
		}
		if (key.equals("left"))
		{
			return getCurrentLeft(request);
		}
		if (key.equals("content"))
		{
			return getCurrentContent(request);
		}
		if (key.equals("noassign"))
		{
			return getCurrentNoAssign(request);
		}
		return null;
	}
	
	private void setCurrentOther(String[] modified, HttpServletRequest request)
	{
		String[] notModified = new String[] {"top","left","content","noassign"};
		for (int i=0; i < modified.length; i++)
		{
			String key = modified[i];
			if (key.equals("top"))
			{
				notModified = removeFromArray(notModified, new String[]{"top"});
			}
			if (key.equals("left"))
			{
				notModified = removeFromArray(notModified, new String[]{"left"});
			}
			if (key.equals("content"))
			{
				notModified = removeFromArray(notModified, new String[]{"content"});
			}
			if (key.equals("noassign"))
			{
				notModified = removeFromArray(notModified, new String[]{"noassign"});
			}
		}
		for (int i=0; i < notModified.length; i++)
		{
			String key = notModified[i];
			setCurrent(key, getCurrent(key, request), request);
		}
	}
	
	private void setCurrent(String key, String[] current, HttpServletRequest request)
	{
		if (key.equals("top"))
		{
			setCurrentTop(current, request);
		}
		if (key.equals("left"))
		{
			setCurrentLeft(current, request);
		}
		if (key.equals("content"))
		{
			setCurrentContent(current, request);
		}
		if (key.equals("noassign"))
		{
			setCurrentNoAssign(current, request);
		}
	}
	
}
