// ------------------------------------------------------------------------------
// DPF.iOS.Classes Wrapped Classes & Interfaces
//
// Dadeh Pardazane Faragir ( DPF ) Co.
//
// Web: http://www.dpfaragir.com
//
// Developed By: Babak Yaghoobi
//
// Email #1: yaghoobi@dpfaragir.com
// Email #2: b_yaghobi@yahoo.com
//
// ------------------------------------------------------------------------------
//
// Licensed 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.
//
// ------------------------------------------------------------------------------
unit DPF.iOS.Classes;

interface

{$I DPF.iOS.Defs.inc}

uses
  System.Classes,
  System.SysUtils,
  System.Math,
{$IFDEF IOS}
  iOSapi.UIKit,
  iOSapi.AVFoundation,
  Macapi.ObjectiveC,
  iOSapi.CocoaTypes,
  iOSapi.CoreGraphics,
  iOSapi.Foundation,
  iOSapi.QuartzCore,
  iOSapi.CoreLocation,

  Macapi.ObjCRuntime, Macapi.CoreFoundation,
  iOSapi.CoreImage, iOSapi.CoreData,
{$ENDIF}
  DPF.iOS.Common,
  System.TypInfo;

const
  libUIKit = '/System/Library/Frameworks/UIKit.framework/UIKit';

{$IFDEF IOS}

const
  UIKeyboardTypeDefault               = 0;
  UIKeyboardAppearanceDefault         = 0;
  UIKeyboardAppearanceAlert           = 1;
  UIKeyboardTypeASCIICapable          = 1;
  UIKeyboardTypeAlphabet              = 1;
  UIKeyboardTypeNumbersAndPunctuation = 2;
  UIKeyboardTypeURL                   = 3;
  UIKeyboardTypeNumberPad             = 4;
  UIKeyboardTypePhonePad              = 5;
  UIKeyboardTypeNamePhonePad          = 6;
  UIKeyboardTypeEmailAddress          = 7;
  UIKeyboardTypeDecimalPad            = 8;
  UIKeyboardTypeTwitter               = 9;

type
{$M+}
  // ------------------------------------------------------------------------------


  NSLockClass = interface(NSObjectClass)
    ['{DD30A910-42FA-455D-ADA8-576655E0E799}']
  end;
  NSLock = interface(NSObject)
    ['{15DCD242-9633-4902-9E6E-7B2948E75BFD}']
    function lockBeforeDate(limit: NSDate): Boolean; cdecl;
    function name: NSString; cdecl;
    procedure setName(n: NSString); cdecl;
    function tryLock: Boolean; cdecl;
    procedure unlock; cdecl;
  end;
  TNSLock = class(TOCGenericImport<NSLockClass, NSLock>)  end;

  // -------------------------------------------------------------
  // CAMediaTiming Protocol Reference
  // -------------------------------------------------------------
  CAMediaTimingClass = interface( NSObjectClass )
    ['{288E5EA2-8BA1-4C2B-A636-BF95114C072A}']
  end;

  CAMediaTiming = interface( NSObject )
    ['{ADB5DEE3-61F3-416E-8B25-4AAB719665A5}']

    function duration: CFTimeInterval; cdecl;
    procedure setDuration( duration: CFTimeInterval ); cdecl;

    function beginTime: CFTimeInterval; cdecl;
    procedure setBeginTime( beginTime: CFTimeInterval ); cdecl;

    function timeOffset: CFTimeInterval; cdecl;
    procedure setTimeOffset( timeOffset: CFTimeInterval ); cdecl;

    function repeatCount: double; cdecl;
    procedure setRepeatCount( repeatCount: double ); cdecl;

    function speed: double; cdecl;
    procedure setSpeed( speed: double ); cdecl;

    function autoreverses: double; cdecl;
    procedure setAutoreverses( autoreverses: double ); cdecl;

    function fillMode: NSString; cdecl;
    procedure setFillMode( fillMode: NSString ); cdecl;

  end;

  // -----------------------------------------------------------------------------
  // CAAnimation Class
  // -----------------------------------------------------------------------------
  CAAnimationClass = interface( CAMediaTimingClass )
    ['{FCBBE880-4AF6-4CF5-B48B-65A9FCDC0C0E}']
    { class } function animation: Pointer; cdecl;
    { class } function defaultValueForKey( key: NSString ): Pointer; cdecl;
  end;

  CAAnimation = interface( CAMediaTiming )
    ['{1F038103-BECA-4A60-89CC-E89CEFD1F06E}']
    function delegate: Pointer; cdecl;
    function isRemovedOnCompletion: Boolean; cdecl;
    procedure setDelegate( delegate: Pointer ); cdecl;
    procedure setRemovedOnCompletion( removedOnCompletion: Boolean ); cdecl;
    procedure setTimingFunction( timingFunction: CAMediaTimingFunction ); cdecl;
    function shouldArchiveValueForKey( key: NSString ): Boolean; cdecl;
    function timingFunction: CAMediaTimingFunction; cdecl;
  end;

  TCAAnimation = class( TOCGenericImport<CAAnimationClass, CAAnimation> )
  end;

  // -----------------------------------------------------------------------------
  // CATransition Class
  // -----------------------------------------------------------------------------
  CATransitionClass = interface( CAAnimationClass )
    ['{96875C05-A8AE-4333-B63F-845BE2BAAAD9}']
  end;

  CATransition = interface( CAAnimation )
    ['{4C940131-542C-485E-B2F1-C6B00484ECDB}']
    function endProgress: Single; cdecl;
    function filter: Pointer; cdecl;
    procedure setEndProgress( endProgress: Single ); cdecl;
    procedure setFilter( filter: Pointer ); cdecl;
    procedure setStartProgress( startProgress: Single ); cdecl;
    procedure setSubtype( subtype: NSString ); cdecl;
    procedure setType( type_: NSString ); cdecl;
    function startProgress: Single; cdecl;
    function subtype: NSString; cdecl;
  end;

  TCATransition = class( TOCGenericImport<CATransitionClass, CATransition> )
  end;

  // -----------------------------------------------------------------------------
  // UIRefreshControl Class
  // -----------------------------------------------------------------------------
  UIRefreshControlClass = interface( UIControlClass )
    ['{1C193A3E-64FC-44F9-91CA-80E951BB45F2}']
  end;

  UIRefreshControl = interface( UIControl )
    ['{DF5CA716-B196-4090-B44D-0DA40C999AB2}']
    function tintColor: UIColor; cdecl;
    procedure setTintColor( tintColor: UIColor ); cdecl;

    function attributedTitle: NSAttributedString; cdecl;
    procedure setAttributedTitle( attributedTitle: NSAttributedString ); cdecl;

    procedure beginRefreshing; cdecl;
    procedure endRefreshing; cdecl;

    function refreshing: boolean; cdecl;
  end;

  TUIRefreshControl = class( TOCGenericImport<UIRefreshControlClass, UIRefreshControl> );

  // ---------------------------------------------------------------------------------------------

  // ----------------------------------------------------------------------------
  // Audio
function AVAudioSessionCategoryPlayAndRecord: NSString;
function AVAudioSessionCategoryPlayback: NSString;
function AVAudioSessionCategoryAmbient: NSString;
function AVAudioSessionCategorySoloAmbient: NSString;
function AVAudioSessionCategoryRecord: NSString;
function AVAudioSessionCategoryAudioProcessing: NSString;
function AVAudioSessionCategoryMultiRoute: NSString;

// ----------------------------------------------------------------------------
function kCAMediaTimingFunctionLinear: NSString;
function kCAMediaTimingFunctionEaseIn: NSString;
function kCAMediaTimingFunctionEaseOut: NSString;
function kCAMediaTimingFunctionEaseInEaseOut: NSString;
function kCAMediaTimingFunctionDefault: NSString;

// ------------------------------------------------------------------------------
// Common Transition Types
function kCATransitionFade: NSString;
function kCATransitionMoveIn: NSString;
function kCATransitionPush: NSString;
function kCATransitionReveal: NSString;

// ------------------------------------------------------------------------------
// Common Transition Subtypes
function kCATransitionFromRight: NSString;
function kCATransitionFromLeft: NSString;
function kCATransitionFromTop: NSString;
function kCATransitionFromBottom: NSString;

// ------------------------------------------------------------------------------
// Fill Modes
function kCAFillModeRemoved: NSString;
function kCAFillModeForwards: NSString;
function kCAFillModeBackwards: NSString;
function kCAFillModeBoth: NSString;
function kCAFillModeFrozen: NSString;

// ------------------------------------------------------------------------------
// Filter Parameter Keys
function kCIInputImageKey: NSString;

// ------------------------------------------------------------------------------
// Keys for Text Attributes Dictionaries
function UITextAttributeFont: NSString;
function UITextAttributeTextColor: NSString;
function UITextAttributeTextShadowColor: NSString;
function UITextAttributeTextShadowOffset: NSString;

// ------------------------------------------------------------------------------
// PDF Creation Functions

procedure UIGraphicsBeginPDFContextToData( data: Pointer { NSMutableData }; bounds: CGRect; documentInfo: NSDictionary ); cdecl; external libUIKit name _PU + 'UIGraphicsBeginPDFContextToData';
function UIGraphicsBeginPDFContextToFile( path: PNSString; bounds: CGRect; documentInfo: NSDictionary ): Boolean; cdecl; external libUIKit name _PU + 'UIGraphicsBeginPDFContextToFile';
procedure UIGraphicsBeginPDFPage; cdecl; external libUIKit name _PU + 'UIGraphicsBeginPDFPage';
procedure UIGraphicsBeginPDFPageWithInfo( bounds: CGRect; pageInfo: NSDictionary ); cdecl; external libUIKit name _PU + 'UIGraphicsBeginPDFPageWithInfo';
procedure UIGraphicsEndPDFContext; cdecl; external libUIKit name _PU + 'UIGraphicsEndPDFContext';

// ------------------------------------------------------------------------------
function CreatePDFfromView( aView: UIView; FileName: string ): Boolean; overload;
function CreatePDFfromView( aViewController: UIViewController; FileName: string ): Boolean; overload;

{$ENDIF}

// ------------------------------------------------------------------------------
implementation

{$IFDEF IOS}

// ------------------------------------------------------------------------------
function kCAFillModeRemoved: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAFillModeRemoved' );
end;

// ------------------------------------------------------------------------------
function kCAFillModeForwards: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAFillModeForwards' );
end;

// ------------------------------------------------------------------------------
function kCAFillModeBackwards: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAFillModeBackwards' );
end;

// ------------------------------------------------------------------------------
function kCAFillModeBoth: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAFillModeBoth' );
end;

// ------------------------------------------------------------------------------
function kCAFillModeFrozen: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAFillModeFrozen' );
end;

// ------------------------------------------------------------------------------
function kCIInputImageKey: NSString;
begin
  result := CocoaNSStringConst( libCoreImage, 'kCIInputImageKey' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategoryPlayAndRecord: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategoryPlayAndRecord' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategoryPlayback: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategoryPlayback' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategoryAmbient: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategoryAmbient' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategorySoloAmbient: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategorySoloAmbient' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategoryRecord: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategoryRecord' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategoryAudioProcessing: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategoryAudioProcessing' );
end;

// ------------------------------------------------------------------------------
function AVAudioSessionCategoryMultiRoute: NSString;
begin
  result := CocoaNSStringConst( libAVFoundation, 'AVAudioSessionCategoryMultiRoute' );
end;

// ------------------------------------------------------------------------------
function kCAMediaTimingFunctionLinear: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAMediaTimingFunctionLinear' );
end;

// ------------------------------------------------------------------------------
function kCAMediaTimingFunctionEaseIn: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAMediaTimingFunctionEaseIn' );
end;

// ------------------------------------------------------------------------------
function kCAMediaTimingFunctionEaseOut: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAMediaTimingFunctionEaseOut' );
end;

// ------------------------------------------------------------------------------
function kCAMediaTimingFunctionEaseInEaseOut: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAMediaTimingFunctionEaseInEaseOut' );
end;

// ------------------------------------------------------------------------------
function kCAMediaTimingFunctionDefault: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCAMediaTimingFunctionDefault' );
end;

function kCATransitionFade: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionFade' );
end;

// ------------------------------------------------------------------------------
function kCATransitionMoveIn: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionMoveIn' );
end;

// ------------------------------------------------------------------------------
function kCATransitionPush: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionPush' );
end;

// ------------------------------------------------------------------------------
function kCATransitionReveal: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionReveal' );
end;

// ------------------------------------------------------------------------------
function UITextAttributeFont: NSString;
begin
  result := CocoaNSStringConst( libUIKit, 'UITextAttributeFont' );
end;

// ------------------------------------------------------------------------------
function kCATransitionFromRight: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionFromRight' );
end;

// ------------------------------------------------------------------------------
function kCATransitionFromLeft: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionFromLeft' );
end;

// ------------------------------------------------------------------------------
function kCATransitionFromTop: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionFromTop' );
end;

// ------------------------------------------------------------------------------
function kCATransitionFromBottom: NSString;
begin
  result := CocoaNSStringConst( libQuartzCore, 'kCATransitionFromBottom' );
end;

// ------------------------------------------------------------------------------
function UITextAttributeTextColor: NSString;
begin
  result := CocoaNSStringConst( libUIKit, 'UITextAttributeTextColor' );
end;

// ------------------------------------------------------------------------------
function UITextAttributeTextShadowColor: NSString;
begin
  result := CocoaNSStringConst( libUIKit, 'UITextAttributeTextShadowColor' );
end;

// ------------------------------------------------------------------------------
function UITextAttributeTextShadowOffset: NSString;
begin
  result := CocoaNSStringConst( libUIKit, 'UITextAttributeTextShadowOffset' );
end;

// ------------------------------------------------------------------------------
function CreatePDFfromUIView( aView: UIView; FileName: string ): Boolean;
var
  pdfData   : NSMutableData;
  pdfContext: CGContextRef;
begin
  result := false;
  // Creates a mutable data object for updating with binary data, like a byte array
  // pdfData := TNSMutableData.Wrap( TNSMutableData.OCClass.data );
  pdfData := TNSMutableData.Create;

  // Points the pdf converter to the mutable data object and to the UIView to be converted
  UIGraphicsBeginPDFContextToData( ( pdfData as ILocalObject ).GetObjectID, aView.bounds, nil );
  UIGraphicsBeginPDFPage( );
  pdfContext := UIGraphicsGetCurrentContext( );

  // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
  aView.layer.renderInContext( pdfContext );

  // remove PDF rendering context
  UIGraphicsEndPDFContext( );
  RemoveFile( FileName );
  if pdfData.length > 0 then
    result := pdfData.writeToFile( NSStr( FileName ), false );
  pdfData.release;
end;

// ------------------------------------------------------------------------------
function CreatePDFfromView( aView: UIView; FileName: string ): Boolean;
begin
  result := CreatePDFfromUIView( aView, FileName );
end;

// ------------------------------------------------------------------------------
function CreatePDFfromView( aViewController: UIViewController; FileName: string ): Boolean;
begin
  result := CreatePDFfromUIView( aViewController.view, FileName );
end;

// ------------------------------------------------------------------------------
initialization

{$ENDIF}

end.
