<%--
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.
--%>

<%@ page import="org.apache.ofbiz.product.catalog.*" %>
<%@ page import="org.apache.ofbiz.product.product.*" %>
<%@ page import="org.apache.ofbiz.entity.*" %>
<%@ page import="org.apache.ofbiz.base.util.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.math.BigDecimal" %>

<jsp:useBean id="delegator" type="org.apache.ofbiz.entity.GenericDelegator" scope="request" />

<%
  List<GenericValue> products = delegator.findList("Product", null, null, null, null, false);
  for (GenericValue product : products) {
    KeywordIndex.indexKeywords(product);
  }

  if(request.getParameter("makeall") == null) {
%>Just added the keywords from all existing product info.
<br/><a href='makebogodata.jsp?makeall=true'>Create a LOT of products, categories, and keywords.</a>
<%
  }
  else {
    String[] wordBag = {"a", "product", "big", "ugly", "pretty", "small", "under", "over", "one", "two", "three", "four", "five", "six", "seven", "eight", "tree"};
    String[] longWordBag = {"b", "item", "little", "cute", "frightening", "massive", "top", "btoom", "bush", "shrub", "gadget"};

    for(int cat=1; cat<=400; cat++)
    {
      String parentId = cat<=20?"CATALOG1":"" + (cat/20);
      delegator.create("ProductCategory", UtilMisc.toMap("productCategoryId", "" + cat, "primaryParentCategoryId", parentId, "description", "Category " + cat));
      delegator.create("ProductCategoryRollup", UtilMisc.toMap("productCategoryId", "" + cat, "parentProductCategoryId", parentId));
      for(int prod=1; prod<=50; prod++)
      {
        String desc = "Cool Description";
        for(int i=0; i<10; i++) {
          int wordNum = (int)(Math.random()*(wordBag.length-1));
          desc += (" " + wordBag[wordNum]);
        }
        String longDesc = "Cool LONG Description";
        for(int i=0; i<50; i++) {
          int wordNum = (int)(Math.random()*(longWordBag.length-1));
          longDesc += (" " + longWordBag[wordNum]);
        }
        BigDecimal price = new BigDecimal("2.99").add(BigDecimal.valueOf(prod));
        GenericValue product = delegator.create("Product", UtilMisc.toMap("productId", "" + (cat*100 + prod), "primaryProductCategoryId", "" + (cat), "productName", "Product " + "" + (cat*100 + prod), "description", desc, "longDescription", longDesc, "defaultPrice", price));
        KeywordIndex.indexKeywords(product);
        delegator.create("ProductCategoryMember", UtilMisc.toMap("productId", "" + (cat*100 + prod), "productCategoryId", "" + (cat)));
      }
    }
%>Created lots of products and categories and keywords.<%
  }
%>
