/* **********************************************************************************
 *
 * Copyright (c) Microsoft Corporation. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for IronPython. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for IronPython, please send an email to ironpy@microsoft.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for IronPython.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;

using IronMath;

namespace IronPython.Runtime {
    public static partial class LongOps {
        #region Generated LongOps

        // *** BEGIN GENERATED CODE ***


        [PythonName("__add__")]
        public static object Add(BigInteger x, object other) {
            if (other is int) return x + ((int)other);
            if (other is Complex64) return x + ((Complex64)other);
            if (other is double) return x + ((double)other);
            if (other is BigInteger) return x + ((BigInteger)other);
            if (other is long) return x + ((long)other);
            return Ops.NotImplemented;
        }


        [PythonName("__sub__")]
        public static object Subtract(BigInteger x, object other) {
            if (other is int) return x - ((int)other);
            if (other is Complex64) return x - ((Complex64)other);
            if (other is double) return x - ((double)other);
            if (other is BigInteger) return x - ((BigInteger)other);
            if (other is long) return x - ((long)other);
            return Ops.NotImplemented;
        }


        [PythonName("__pow__")]
        public static object Power(BigInteger x, object other) {
            if (other is int) return Power(x, (int)other);
            if (other is BigInteger) return Power(x, (BigInteger)other);
            if (other is long) return Power(x, (long)other);
            return Ops.NotImplemented;
        }


        [PythonName("__mul__")]
        public static object Multiply(BigInteger x, object other) {
            if (other is int) return x * ((int)other);
            if (other is Complex64) return x * ((Complex64)other);
            if (other is double) return x * ((double)other);
            if (other is BigInteger) return x * ((BigInteger)other);
            if (other is long) return x * ((long)other);
            return Ops.NotImplemented;
        }


        [PythonName("__floordiv__")]
        public static object FloorDivide(BigInteger x, object other) {
            if (other is int) return Divide(x, (int)other);
            if (other is Complex64) {
                Complex64 y = (Complex64)other;
                if(y.IsZero) throw Ops.ZeroDivisionError();
                return ComplexOps.FloorDivide(Complex64.MakeReal(x), y);
            }
            if (other is double) {
                double y =  (double)other;
                if(y == 0) throw Ops.ZeroDivisionError();

                return x / y;
            }
            if (other is long) return Divide(x, (long)other);
            if (other is BigInteger) return Divide(x, (BigInteger)other);
            return Ops.NotImplemented;
        }


        [PythonName("__div__")]
        public static object TrueDivide(BigInteger x, object other) {
            if (other is int) return TrueDivide(x, (int)other);
            if (other is BigInteger) return TrueDivide(x, (BigInteger)other);
            if (other is long) return TrueDivide(x, (long)other);
            return Ops.NotImplemented;
        }


        [PythonName("__mod__")]
        public static object Mod(BigInteger x, object other) {
            if (other is int) return Mod(x, (int)other);
            if (other is Complex64) {
                Complex64 y = (Complex64)other;
                if(y.IsZero) throw Ops.ZeroDivisionError();
                return ComplexOps.Mod(Complex64.MakeReal(x), y);
            }
            if (other is double) {
                double y =  (double)other;
                if(y == 0) throw Ops.ZeroDivisionError();

                return x % y;
            }
            if (other is long) return Mod(x, (long)other);
            if (other is BigInteger) return Mod(x, (BigInteger)other);
            return Ops.NotImplemented;
        }


        [PythonName("__and__")]
        public static object BitwiseAnd(BigInteger x, object other) {
            if (other is BigInteger) return x & (BigInteger)other;
            if (other is long) return x & (long)other;
            if (other is int) return x & (int)other;
            return Ops.NotImplemented;
        }


        [PythonName("__or__")]
        public static object BitwiseOr(BigInteger x, object other) {
            if (other is BigInteger) return x | (BigInteger)other;
            if (other is long) return x | (long)other;
            if (other is int) return x | (int)other;
            return Ops.NotImplemented;
        }


        [PythonName("__xor__")]
        public static object Xor(BigInteger x, object other) {
            if (other is BigInteger) return x ^ (BigInteger)other;
            if (other is long) return x ^ (long)other;
            if (other is int) return x ^ (int)other;
            return Ops.NotImplemented;
        }


        // *** END GENERATED CODE ***

        #endregion

    }
}
