package org.nutz.mvc.view;

import java.util.Iterator;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.nutz.lang.Mirror;
import org.nutz.lang.Strings;
import org.nutz.lang.segment.CharSegment;
import org.nutz.lang.segment.Segment;
import org.nutz.mvc.View;

/**
 * 重定向视图
 * <p>
 * 在入口函数上声明：
 * <p>
 * '@Ok("redirect:/pet/list.nut")'
 * <p>
 * 实际上相当于：<br>
 * new ServerRedirectView("/pet/list.nut");
 * 
 * @author zozoh(zozohtnt@gmail.com)
 */
public class ServerRedirectView implements View {

	private Segment dest;

	public ServerRedirectView(String dest) {
		this.dest = new CharSegment(Strings.trim(dest));
	}

	public void render(HttpServletRequest req, HttpServletResponse resp, Object obj)
			throws Exception {
		Mirror<?> mirror = Mirror.me(obj);

		// Fill path
		Set<String> keySet = dest.keys();
		Iterator<String> it = keySet.iterator();
		while (it.hasNext()) {
			String key = it.next();
			Object value = null;
			int length = key.length();
			if (null != mirror && key.startsWith("obj.") && length > 4) {
				value = mirror.getValue(obj, key.substring(4));
			} else if (key.startsWith("p.") && length > 2) {
				value = req.getParameter(key.substring(2));
			} else {
				value = obj;
			}
			if (null == value)
				value = obj;
			dest.set(key, value);
		}

		// Format the path ...
		String path = dest.toString();
		
		// Another site
		if (path.startsWith("http://") || path.startsWith("https://")) {}
		// Absolute path, add the context path for it
		else if (path.startsWith("/")) {
			path = req.getContextPath() + path;
		}
		// Relative path, add current URL path for it
		else {
			String myPath = req.getPathInfo();
			int pos = myPath.lastIndexOf('/');
			if (pos > 0)
				path = myPath.substring(0, pos) + "/" + path;
			else
				path = "/" + path;
		}
		resp.sendRedirect(path);
		resp.flushBuffer();
	}
}

@@ -47,24 +47,47 @@
 .Iterator;%0D%0A
+import java.util.Map;%0D%0A
 import java.
@@ -742,24 +742,52 @@
 t));%0D%0A%09%7D%0D%0A%0D%0A
+%09// TODO %E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E5%86%99%E7%9A%84%E6%9C%89%E7%82%B9%E7%83%82%EF%BC%8C%E6%9C%89%E6%97%B6%E9%97%B4%E9%87%8D%E6%9E%84%E4%B8%80%E4%B8%8B%0D%0A
 %09public void
@@ -917,16 +917,112 @@
 e(obj);%0D
+%0A%09%09boolean isMap = null != obj && obj instanceof Map%3C?, ?%3E;%0D%0A%09%09Map%3C?, ?%3E map = (Map%3C?, ?%3E) obj;%0D
 %0A%0D%0A%09%09// 
@@ -1234,26 +1234,8 @@
 if (
-null != mirror && 
 key.
@@ -1246,19 +1246,17 @@
 tsWith(%22
-obj
+p
 .%22) && l
@@ -1263,17 +1263,17 @@
 ength %3E 
-4
+2
 ) %7B%0D%0A%09%09%09
@@ -1285,29 +1285,25 @@
 e = 
-mirror.getValue(obj, 
+req.getParameter(
 key.
@@ -1316,9 +1316,9 @@
 ing(
-4
+2
 ));%0D
@@ -1326,18 +1326,42 @@
 %09%09%09%7D
- else if (
+%0D%0A%09%09%09// Map%0D%0A%09%09%09else if (isMap && 
 key.
@@ -1364,33 +1364,35 @@
 key.startsWith(%22
-p
+obj
 .%22) && length %3E 
@@ -1383,33 +1383,33 @@
 .%22) && length %3E 
-2
+4
 ) %7B%0D%0A%09%09%09%09value =
@@ -1409,33 +1409,153 @@
 value = 
-req
+map
 .get
-Parameter(
+(key);%0D%0A%09%09%09%7D%0D%0A%09%09%09// POJO%0D%0A%09%09%09else if (null != mirror && key.startsWith(%22obj.%22) && length %3E 4) %7B%0D%0A%09%09%09%09value = mirror.getValue(obj, 
 key.subs
@@ -1552,33 +1552,33 @@
 , key.substring(
-2
+4
 ));%0D%0A%09%09%09%7D else %7B
@@ -1570,17 +1570,41 @@
 );%0D%0A%09%09%09%7D
- 
+%0D%0A%09%09%09// Normal value%0D%0A%09%09%09
 else %7B%0D%0A
@@ -1761,18 +1761,16 @@
 ing();%0D%0A
-%09%09
 %0D%0A%09%09// A

add support for map