/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (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.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.dynamo.script;

import java.util.*;
import com.silverwrist.util.*;
import com.silverwrist.dynamo.db.ImageStore;
import com.silverwrist.dynamo.db.UserManagement;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.mail.MailMessageProvider;
import com.silverwrist.dynamo.module.ModuleOperations;
import com.silverwrist.dynamo.security.SecurityReferenceMonitor;

public class LibraryCast
{
  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  LibraryCast()
  { // do nothing
  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal operations
   *--------------------------------------------------------------------------------
   */

  private final Object query(Object obj, Class klass)
  {
    if (obj==null)
      return null;
    if (klass.isInstance(obj))
      return obj;
    if ((klass!=ServiceProvider.class) && (obj instanceof ServiceProvider))
    { // try using ServiceProvider
      try
      { // query for this object as a service
	return ((ServiceProvider)obj).queryService(klass);

      } // end try
      catch (NoSuchServiceException e)
      { // do nothing with this exception
      } // end catch

    } // end if

    throw new ClassCastException("object is not an instance of " + klass.getName());

  } // end query

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  public final Boolean booleanObject(boolean b)
  {
    return (b ? Boolean.TRUE : Boolean.FALSE);

  } // end booleanObject

  public final ChainParameterInput queryChainParameterInput(Object obj)
  {
    return (ChainParameterInput)query(obj,ChainParameterInput.class);

  } // end queryChainParameterInput

  public final CookieControl queryCookieControl(Object obj)
  {
    return (CookieControl)query(obj,CookieControl.class);

  } // end queryCookieControl

  public final DialogLoader queryDialogLoader(Object obj)
  {
    return (DialogLoader)query(obj,DialogLoader.class);

  } // end queryDialogLoader

  public final DynamoUser queryDynamoUser(Object obj)
  {
    return (DynamoUser)query(obj,DynamoUser.class);

  } // end queryDynamoUser

  public final ImageStore queryImageStore(Object obj)
  {
    return (ImageStore)query(obj,ImageStore.class);

  } // end queryImageStore

  public final MailMessageProvider queryMailMessageProvider(Object obj)
  {
    return (MailMessageProvider)query(obj,MailMessageProvider.class);

  } // end queryMailMessageProvider

  public final ModuleOperations queryModuleOperations(Object obj)
  {
    return (ModuleOperations)query(obj,ModuleOperations.class);

  } // end queryModuleOperations

  public final ObjectProvider queryObjectProvider(Object obj)
  {
    return (ObjectProvider)query(obj,ObjectProvider.class);

  } // end queryObjectProvider

  public final SecurityReferenceMonitor querySecurityReferenceMonitor(Object obj)
  {
    return (SecurityReferenceMonitor)query(obj,SecurityReferenceMonitor.class);

  } // end querySecurityReferenceMonitor

  public final ServiceProvider queryServiceProvider(Object obj)
  {
    return (ServiceProvider)query(obj,ServiceProvider.class);

  } // end queryServiceProvider

  public final URLRewriter queryURLRewriter(Object obj)
  {
    return (URLRewriter)query(obj,URLRewriter.class);

  } // end queryURLRewriter

  public final UserManagement queryUserManagement(Object obj)
  {
    return (UserManagement)query(obj,UserManagement.class);

  } // end queryUserManagement

  public final boolean toBoolean(Object o)
  {
    if (o==null)
      return false;
    if (o instanceof Boolean)
      return ((Boolean)o).booleanValue();
    if (o instanceof Number)
      return (((Number)o).intValue()!=0);
    String s = o.toString();
    if (StringUtils.isBooleanTrue(s))
      return true;
    if (StringUtils.isBooleanFalse(s))
      return false;
    throw new ClassCastException("LibraryCast.toBoolean: invalid cast");

  } // end toBoolean

  public final Boolean toBooleanObject(Object o)
  {
    if (o==null)
      return Boolean.FALSE;
    if (o instanceof Boolean)
      return (Boolean)o;
    if (o instanceof Number)
      return Boolean.valueOf(((Number)o).intValue()!=0);
    String s = o.toString();
    if (StringUtils.isBooleanTrue(s))
      return Boolean.TRUE;
    if (StringUtils.isBooleanFalse(s))
      return Boolean.FALSE;
    throw new ClassCastException("LibraryCast.toBooleanObject: invalid cast");

  } // end toBooleanObject

  public final byte[] toByteArray(Object o)
  {
    if (o instanceof byte[])
      return (byte[])o;
    throw new ClassCastException("LibraryCast.toByteArray: invalid cast");

  } // end toByteArray

  public final Country toCountry(Object o)
  {
    if (o instanceof Country)
      return (Country)o;
    Country rc = International.get().getCountryForCode(o.toString());
    if (rc==null)
      throw new ClassCastException("LibraryCast.toCountry: invalid cast");
    return rc;

  } // end toCountry

  public final Date toDate(Object o)
  {
    if (o instanceof Date)
      return (Date)o;
    throw new ClassCastException("LibraryCast.toDate: invalid cast");

  } // end toDate

  public final double toDouble(Object o) throws NumberFormatException
  {
    if (   (o instanceof Byte) || (o instanceof Short) || (o instanceof Integer) || (o instanceof Long)
        || (o instanceof Float) || (o instanceof Double))
      return ((Number)o).doubleValue();
    else
      return Double.parseDouble(o.toString());

  } // end toDouble

  public final Double toDoubleObject(Object o) throws NumberFormatException
  {
    if (   (o instanceof Byte) || (o instanceof Short) || (o instanceof Integer) || (o instanceof Long)
        || (o instanceof Float) || (o instanceof Double))
      return new Double(((Number)o).doubleValue());
    else
      return new Double(o.toString());

  } // end toDouble

  public final DynamicClass toDynamicClass(Object o) throws ClassCastException
  {
    if (o instanceof DynamicClass)
      return (DynamicClass)o;
    throw new ClassCastException("LibraryCast.toDynamicClass: invalid cast");
    
  } // end toDynamicClass

  public final DynamicObject toDynamicObject(Object o) throws ClassCastException
  {
    if (o instanceof DynamicObject)
      return (DynamicObject)o;
    throw new ClassCastException("LibraryCast.toDynamicObject: invalid cast");
    
  } // end toDynamicObject

  public final int toInteger(Object o) throws NumberFormatException
  {
    if ((o instanceof Byte) || (o instanceof Short) || (o instanceof Integer))
      return ((Number)o).intValue();
    else if ((o instanceof Float) || (o instanceof Double))
      return Math.round(((Number)o).floatValue());
    else if (o instanceof Boolean)
      return ((Boolean)o).booleanValue() ? 1 : 0;
    else
      return Integer.parseInt(o.toString());

  } // end toInteger

  public final Integer toIntegerObject(Object o) throws NumberFormatException
  {
    if ((o instanceof Byte) || (o instanceof Short) || (o instanceof Integer))
      return new Integer(((Number)o).intValue());
    else if ((o instanceof Float) || (o instanceof Double))
      return new Integer(Math.round(((Number)o).floatValue()));
    else if (o instanceof Boolean)
      return new Integer(((Boolean)o).booleanValue() ? 1 : 0);
    else
      return new Integer(o.toString());

  } // end toIntegerObject

  public final List toList(Object o)
  {
    if (o instanceof List)
      return (List)o;
    throw new ClassCastException("LibraryCast.toList: invalid cast");

  } // end toList

  public final Map toMap(Object o)
  {
    if (o instanceof Map)
      return (Map)o;
    throw new ClassCastException("LibraryCast.toMap: invalid cast");

  } // end toMap

  public final OptionSet toOptionSet(Object o)
  {
    if (o instanceof OptionSet)
      return (OptionSet)o;
    throw new ClassCastException("LibraryCast.toOptionSet: invalid cast");

  } // end toOptionSet

  public final Throwable toThrowable(Object o)
  {
    if (o instanceof Throwable)
      return (Throwable)o;
    throw new ClassCastException("LibraryCast.toThrowable: invalid cast");

  } // end toThrowable

} // end class LibraryCast
