using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;

/*============================================================================
  File:     FibSeq.cs

  Summary:  The .NET table-values function will be used to
            show the performance improvement gained by using
			SQL Server 2008's ordered table-value (CLR-based) function feature.
			
			NOTE: Using the ORDER BY keyword in CREATE FUNCTION is not 
			supported by Visual Studio autodeploy. Use the script provided and manual
			assembly and function deployment.

  Date:     August 2008

  SQL Server Version: 10.0.1600.22 (RTM)
------------------------------------------------------------------------------
  Written by Bob Beauchemin, SQLskills.com

  For more scripts and sample code, check out http://www.SQLskills.com

  This script is intended only as a supplement to SQL Server Jumpstart program.
  
  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF 
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 
  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
============================================================================*/

public partial class FData : IEnumerator, IEnumerable
{
	// the previous number in the sequence
	int previous_;
	// the current number in the sequence
	int current_;
	int count_;
	int maxCount_;
    int preStart;
    int start;

	internal FData(int preStart, int start, int count)
	{
        this.preStart = preStart;
        this.start = start;
		previous_ = preStart;
		current_ = start;
		maxCount_ = count;
		this.count_ = 0;
	}

	// One IEnumerable method
	public IEnumerator GetEnumerator()
	{
		return this;
	}
	
	// Three IEnumerator methods.
	public bool 	MoveNext ()	
	{
		// just leave things as they are
		// for the first time though
		if (count_ != 0)
		{
			int p = current_;
			current_ += previous_;
			previous_ = p;
		}
		// move to next number in sequence
		count_ = count_ + 1;
		if (count_ > maxCount_)
		{
			// done with sequence
			return false;
		}
		return true;
	}
	public object 	Current 	{  get  { return this; } }
	public void 	Reset ()	
	{
		this.count_ = 0;
        previous_ = preStart;
        current_ = start;
        
	}

	// Two Tvf contract methods
	[Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FillRow",TableDefinition="next int, prev int")]
	public static IEnumerable Fibonacci(int a, int b, int c)
	{
		return new FData(a,b,c);
	}

	public static void FillRow(Object obj, out int nextout, out int prevout)
	{
		FData f = (FData)obj;

		nextout = f.current_;
		prevout = f.previous_;
	}

};

