/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket.panels;

import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.Response;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.protocol.http.ClientProperties;
import org.apache.wicket.protocol.http.WebRequestCycle;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.protocol.http.request.WebClientInfo;
import org.apache.wicket.request.ClientInfo;
import org.apache.wicket.util.value.IValueMap;

/**
 * https://cwiki.apache.org/WICKET/object-container-adding-flash-to-a-wicket-application.html
 */
public abstract class ObjectContainer extends WebMarkupContainer {

	private static final long serialVersionUID = 1L;

	// Some general attributes for the object tag:
	private static final String ATTRIBUTE_CONTENTTYPE = "type";
	private static final String ATTRIBUTE_CLASSID = "classid";
	private static final String ATTRIBUTE_CODEBASE = "codebase";

	// This is used for browser specific adjustments
	private ClientProperties clientProperties = null;

	public ObjectContainer(String id) {
		super(id);
	}

	// Set an attribute/property
	public abstract void setValue(String name, String value);

	// Get an attribute/property
	public abstract String getValue(String name);

	// Set the object's content type
	protected abstract String getContentType();

	// Set the object's clsid (for IE)
	protected abstract String getClsid();

	// Where to get the browser plugin (for IE)
	protected abstract String getCodebase();

	// Object's valid attribute names
	protected abstract List<String> getAttributeNames();

	// Object's valid parameter names
	protected abstract List<String> getParameterNames();

	// Utility function to get the URL for the object's data
	protected String resolveResource(String src) {
		// if it's an absolute path, return it:
		if (src.startsWith("/") || src.startsWith("http://") || src.startsWith("https://"))
			return (src);

		// use the parent container class to resolve the resource reference
		Component parent = getParent();
		if (parent instanceof Fragment) {
			// must check for fragment, otherwise we end up in Wicket namespace
			parent = parent.getParent();
		}
		if (parent != null) {
			ResourceReference resRef = new ResourceReference(parent.getClass(), src, false);
			return (urlFor(resRef).toString());
		}

		return (src);
	}

	@Override
	public void onComponentTag(ComponentTag tag) {
		super.onComponentTag(tag);

		// get the attributes from the html-source
		IValueMap attributeMap = tag.getAttributes();

		// set the content type
		String contentType = getContentType();
		if (contentType != null && !"".equals(contentType))
			attributeMap.put(ATTRIBUTE_CONTENTTYPE, contentType);

		// set clsid and codebase for IE
		if (getClientProperties().isBrowserInternetExplorer()) {
			String clsid = getClsid();
			String codeBase = getCodebase();

			if (clsid != null && !"".equals(clsid))
				attributeMap.put(ATTRIBUTE_CLASSID, clsid);
			if (codeBase != null && !"".equals(codeBase))
				attributeMap.put(ATTRIBUTE_CODEBASE, codeBase);
		}

		// add all attributes
		for (String name : getAttributeNames()) {
			String value = getValue(name);
			if (value != null)
				attributeMap.put(name, value);
		}
	}

	@Override
	public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
		Response response = getResponse();
		response.write("\n");

		// add all object's parameters:
		for (String name : getParameterNames()) {
			String value = getValue(name);
			if (value != null) {
				response.write("<param name=\"");
				response.write(name);
				response.write("\" value=\"");
				response.write(value);
				response.write("\"/>\n");
			}
		}

		super.onComponentTagBody(markupStream, openTag);
	}

	// shortcut to the client properties:
	protected ClientProperties getClientProperties() {
		if (clientProperties == null) {
			ClientInfo clientInfo = WebSession.get().getClientInfo();

			if (clientInfo == null || !(clientInfo instanceof WebClientInfo)) {
				clientInfo = new WebClientInfo((WebRequestCycle) getRequestCycle());
				WebSession.get().setClientInfo(clientInfo);
			}

			clientProperties = ((WebClientInfo) clientInfo).getProperties();
		}
		return (clientProperties);
	}
}