//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
using System;
using System.Runtime.InteropServices;

namespace COMInteropSamples
{
	/// <summary>
	/// Podsumowanie dla Arithmetic.
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct Complex 
	{
		public double real;
		public double imaginary;
		public void Polar(out double r, out double t)
		{ 
			r = Math.Sqrt(real*real + imaginary * imaginary);
			t = Math.Atan2(imaginary, real);
		}
	}
	public enum ArithmeticErrors
	{
		DivideByZero = 0,
		Overflow,
		Underflow
	}

	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IBasicOperations
	{
		int Add(int a, int b);
		int Subtract(int a, int b);
		int Multiply(int a, int b);
		int Divide(int a, int b);
		Complex Add(Complex a, Complex b);
		ArithmeticErrors LastError
		{
			get;
		}
	}

	[ClassInterface(ClassInterfaceType.None)]
	public class Arithmetic : IBasicOperations
	{
		ArithmeticErrors error;
		public Complex Add(Complex a, Complex b)
		{
			Complex c;
			c.real = a.real + b.real;
			c.imaginary = a.imaginary + b.imaginary;
			return c;
		}
		public ArithmeticErrors LastError
		{
			get
			{
				return error;
			}
		}
		public int Add(int a, int b)
		{
			return a + b;
		}
		public int Subtract(int a, int b)
		{
			return a - b;
		}
		public int Multiply(int a, int b)
		{
			return a * b;
		}
		public int Divide(int a, int b)
		{
			if(b != 0)
				return a / b;
			else
			{
				error = ArithmeticErrors.DivideByZero;
				return 0;
			}
		}
	}
}
