/*******************************************************************************
 * 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 org.apache.ofbiz.widget.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

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

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor;
import org.apache.ofbiz.base.util.collections.MapStack;
import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
import org.apache.ofbiz.webapp.control.RequestHandler;
import org.apache.ofbiz.widget.WidgetWorker;
import org.apache.ofbiz.widget.renderer.ScreenStringRenderer;
import org.w3c.dom.Element;


/**
 * Widget Library - Screen model HTML class
 */
@SuppressWarnings("serial")
public class IterateSectionWidget extends ModelScreenWidget {

    public static final String module = IterateSectionWidget.class.getName();
    public static int DEFAULT_PAGE_SIZE = 5;
    public static int MAX_PAGE_SIZE = 10000;

    private final List<ModelScreenWidget.Section> sectionList;
    private final FlexibleMapAccessor<Object> listNameExdr;
    private final FlexibleStringExpander entryNameExdr;
    private final FlexibleStringExpander keyNameExdr;
    private final FlexibleStringExpander paginateTarget;
    private final FlexibleStringExpander paginate;
    private final int viewSize;

    public IterateSectionWidget(ModelScreen modelScreen, Element iterateSectionElement) {
        super(modelScreen, iterateSectionElement);
        String listName = iterateSectionElement.getAttribute("list");
        if (listName.isEmpty()) {
            listName = iterateSectionElement.getAttribute("list-name");
        }
        this.listNameExdr = FlexibleMapAccessor.getInstance(listName);
        String entryName = iterateSectionElement.getAttribute("entry");
        if (entryName.isEmpty()) {
            entryName = iterateSectionElement.getAttribute("entry-name");
        }
        this.entryNameExdr = FlexibleStringExpander.getInstance(entryName);
        String keyName = iterateSectionElement.getAttribute("key");
        if (keyName.isEmpty()) {
            keyName = iterateSectionElement.getAttribute("key-name");
        }
        this.keyNameExdr = FlexibleStringExpander.getInstance(keyName);
        this.paginateTarget = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate-target"));
        this.paginate = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate"));
        int viewSize = DEFAULT_PAGE_SIZE;
        String viewSizeStr = iterateSectionElement.getAttribute("view-size");
        if (!viewSizeStr.isEmpty()) {
            viewSize = Integer.parseInt(viewSizeStr);
        }
        this.viewSize = viewSize;
        List<? extends Element> childElementList = UtilXml.childElementList(iterateSectionElement);
        if (childElementList.isEmpty()) {
            this.sectionList = Collections.emptyList();
        } else {
            List<ModelScreenWidget.Section> sectionList = new ArrayList<ModelScreenWidget.Section>(childElementList.size());
            for (Element sectionElement: childElementList) {
                ModelScreenWidget.Section section = new ModelScreenWidget.Section(modelScreen, sectionElement, false);
                sectionList.add(section);
            }
            this.sectionList = Collections.unmodifiableList(sectionList);
        }
    }

    public List<ModelScreenWidget.Section> getSectionList() {
        return sectionList;
    }

    @Override
    public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
        int viewIndex = 0;
        int viewSize = this.viewSize;
        int lowIndex = -1;
        int highIndex = -1;
        int listSize = 0;
        int actualPageSize = 0;

        boolean isEntrySet = false;
        // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
        MapStack<String> contextMs = MapStack.create(context);

        String entryName = this.entryNameExdr.expandString(context);
        String keyName = this.keyNameExdr.expandString(context);
        Object obj = listNameExdr.get(context);
        if (obj == null) {
            Debug.logError("No object found for listName:" + listNameExdr.toString(), module);
            return;
        }
        List<?> theList = null;
        if (obj instanceof Map<?, ?>) {
            Set<Map.Entry<String, Object>> entrySet = UtilGenerics.<Map<String, Object>>cast(obj).entrySet();
            Object [] a = entrySet.toArray();
            theList = Arrays.asList(a);
            isEntrySet = true;
        } else if (obj instanceof List<?>) {
            theList = (List<?>)obj;
        } else {
            Debug.logError("Object not list or map type", module);
            return;
        }
        listSize = theList.size();
        WidgetWorker.incrementPaginatorNumber(context);
        int startPageNumber = WidgetWorker.getPaginatorNumber(context);

        if (getPaginate(context)) {
            try {
                Map<String, String> params = UtilGenerics.cast(context.get("parameters"));
                String viewIndexString = params.get("VIEW_INDEX" + "_" + WidgetWorker.getPaginatorNumber(context));
                String viewSizeString = params.get("VIEW_SIZE" + "_" + WidgetWorker.getPaginatorNumber(context));
                viewIndex = Integer.parseInt(viewIndexString);
                viewSize = Integer.parseInt(viewSizeString);
            } catch (Exception e) {
                try {
                    viewIndex = ((Integer) context.get("viewIndex")).intValue();
                } catch (Exception e2) {
                    viewIndex = 0;
                }
            }
            context.put("viewIndex", Integer.valueOf(viewIndex));
            lowIndex = viewIndex * viewSize;
            highIndex = (viewIndex + 1) * viewSize;
        } else {
            viewIndex = 0;
            viewSize = MAX_PAGE_SIZE;
            lowIndex = 0;
            highIndex = MAX_PAGE_SIZE;
        }
        Iterator<?> iter = theList.iterator();
        int itemIndex = -1;
        int iterateIndex = 0;
        while (iter.hasNext()) {
            itemIndex++;
            if (itemIndex >= highIndex) {
                break;
            }
            Object item = iter.next();
            if (itemIndex < lowIndex) {
                continue;
            }
            if (isEntrySet) {
                Map.Entry<String, ?> entry = UtilGenerics.cast(item);
                contextMs.put(entryName, entry.getValue());
                contextMs.put(keyName, entry.getKey());
            } else {
                contextMs.put(entryName, item);
            }
            contextMs.put("itemIndex", Integer.valueOf(itemIndex));

            if (iterateIndex < listSize) {
                contextMs.put("iterateId",String.valueOf(entryName+iterateIndex));
                iterateIndex++;
            }
            for (ModelScreenWidget.Section section: this.sectionList) {
                section.renderWidgetString(writer, contextMs, screenStringRenderer);
            }
        }

        if ((itemIndex + 1) < highIndex) {
            highIndex = itemIndex + 1;
        }
        actualPageSize = highIndex - lowIndex;
        if (getPaginate(context)) {
            try {
                Integer lastPageNumber = null;
                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
                if (globalCtx != null) {
                    lastPageNumber = (Integer)globalCtx.get("PAGINATOR_NUMBER");
                    globalCtx.put("PAGINATOR_NUMBER", Integer.valueOf(startPageNumber));
                }
                renderNextPrev(writer, context, listSize, actualPageSize);
                if (globalCtx != null) {
                    globalCtx.put("PAGINATOR_NUMBER", lastPageNumber);
                }
            } catch (IOException e) {
                Debug.logError(e, module);
                throw new RuntimeException(e.getMessage());
            }
        }

    }
    /*
     * @return
     */
    public String getPaginateTarget(Map<String, Object> context) {
        return this.paginateTarget.expandString(context);
    }

    public boolean getPaginate(Map<String, Object> context) {
        if (!this.paginate.isEmpty() && UtilValidate.isNotEmpty(this.paginate.expandString(context))) {
            return Boolean.valueOf(this.paginate.expandString(context)).booleanValue();
        } else {
            return true;
        }
    }

    public int getViewSize() {
        return viewSize;
    }

    public void renderNextPrev(Appendable writer, Map<String, Object> context, int listSize, int actualPageSize) throws IOException {
        String targetService = this.getPaginateTarget(context);
        if (targetService == null) {
            targetService = "${targetService}";
        }

        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
        if (UtilValidate.isNotEmpty(queryStringMap)) {
            inputFields.putAll(queryStringMap);
        }

        String queryString = UtilHttp.urlEncodeArgs(inputFields);
        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);




        if (UtilValidate.isEmpty(targetService)) {
            Debug.logWarning("TargetService is empty.", module);
            return;
        }

        int viewIndex = -1;
        try {
            viewIndex = ((Integer) context.get("viewIndex")).intValue();
        } catch (Exception e) {
            viewIndex = 0;
        }

        int viewSize = -1;
        try {
            viewSize = ((Integer) context.get("viewSize")).intValue();
        } catch (Exception e) {
            viewSize = this.getViewSize();
        }


        /*
        int highIndex = -1;
        try {
            highIndex = modelForm.getHighIndex();
        } catch (Exception e) {
            highIndex = 0;
        }

        int lowIndex = -1;
        try {
            lowIndex = modelForm.getLowIndex();
        } catch (Exception e) {
            lowIndex = 0;
        }
         */

        int lowIndex = viewIndex * viewSize;
        int highIndex = (viewIndex + 1) * viewSize;
        // if this is all there seems to be (if listSize < 0, then size is unknown)
        if (actualPageSize >= listSize && listSize > 0) {
            return;
        }

        HttpServletRequest request = (HttpServletRequest) context.get("request");
        HttpServletResponse response = (HttpServletResponse) context.get("response");

        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");

        writer.append("<table border=\"0\" width=\"100%\" cellpadding=\"2\">\n");
        writer.append("  <tr>\n");
        writer.append("    <td align=\"right\">\n");
        writer.append("      <b>\n");
        if (viewIndex > 0) {
            writer.append(" <a href=\"");
            StringBuilder linkText = new StringBuilder(targetService);
            if (linkText.indexOf("?") < 0)  linkText.append("?");
            else linkText.append("&amp;");
            //if (queryString != null && !queryString.equals("null")) linkText += queryString + "&";
            if (UtilValidate.isNotEmpty(queryString)) {
                linkText.append(queryString).append("&amp;");
            }
            linkText.append("VIEW_SIZE_"+ paginatorNumber + "=").append(viewSize).append("&amp;VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex - 1).append("\"");

            // make the link
            writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false));
            String previous = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", (Locale) context.get("locale"));
            writer.append(" class=\"buttontext\">[").append(previous).append("]</a>\n");

        }
        if (listSize > 0) {
            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
            String commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
            writer.append(" <span class=\"tabletext\">").append(commonDisplaying).append("</span> \n");
        }
        if (highIndex < listSize) {
            writer.append(" <a href=\"");
            StringBuilder linkText = new StringBuilder(targetService);
            if (linkText.indexOf("?") < 0)  linkText.append("?");
            else linkText.append("&amp;");
            if (UtilValidate.isNotEmpty(queryString)) {
                linkText.append(queryString).append("&amp;");
            }
            linkText.append("VIEW_SIZE_" + paginatorNumber + "=").append(viewSize).append("&amp;VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex + 1).append("\"");

            // make the link
            writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false));
            String next = UtilProperties.getMessage("CommonUiLabels", "CommonNext", (Locale) context.get("locale"));
            writer.append(" class=\"buttontext\">[").append(next).append("]</a>\n");

        }
        writer.append("      </b>\n");
        writer.append("    </td>\n");
        writer.append("  </tr>\n");
        writer.append("</table>\n");

    }

    @Override
    public void accept(ModelWidgetVisitor visitor) throws Exception {
        visitor.visit(this);
    }

    public FlexibleMapAccessor<Object> getListNameExdr() {
        return listNameExdr;
    }

    public FlexibleStringExpander getEntryNameExdr() {
        return entryNameExdr;
    }

    public FlexibleStringExpander getKeyNameExdr() {
        return keyNameExdr;
    }

    public FlexibleStringExpander getPaginateTarget() {
        return paginateTarget;
    }

    public FlexibleStringExpander getPaginate() {
        return paginate;
    }

}


