unit step81;

interface
  function  LIBRARYID: Cardinal; pascal;
  procedure LIBRARYENTRY( command: WORD ); pascal;

implementation
uses
  Windows,
  SysUtils,
  LDefin2D,
  ksConstTLB,
  ksAuto,
{$IFDEF __LIGHT_VERSION__}
  klTLB;
{$ELSE}
  ksTLB;
{$ENDIF}

var
  kompas : KompasObject;
  doc    : ksDocument2D;
  attr   : ksAttributeObject;

//------------------------------------------------------------------------------
// LibraryId
//---
function LIBRARYID: Cardinal; pascal;
begin
  Result := 100;
end;

//-------------------------------------------------------------------------------
//   
// ---
procedure FuncAttrType();
var
  col      : ksColumnInfoParam;
  type_    : ksAttributeTypeParam;
  arr      : ksDynamicArray;
  nameFile : AnsiString;
  numbType : double;
begin
  col := ksColumnInfoParam( kompas.GetParamStruct(ko_ColumnInfoParam) );
  type_ := ksAttributeTypeParam( kompas.GetParamStruct(ko_AttributeType) );
  if col <> nil then begin
	  if ( type_ <> nil ) and ( col <> nil ) then begin
		  type_.Init();
		  col.Init();
		  type_.Header := 'double_str_long';  // o- 
		  type_.RowsCount := 1;    		 			  // -   
		  type_.FlagVisible := true;          // ,     
		  type_.Password := '';               // ,      -     
      type_.Key1 := 10;
		  type_.Key2 := 20;
		  type_.Key3 := 30;
		  type_.Key4 := 0;

      arr := ksDynamicArray( type_.GetColumns() );
  		if arr <> nil then begin
        //    
        col.Header := 'double';        // o- 
        col.type_ := DOUBLE_ATTR_TYPE; //     - .
        col.Key := 0;                  //  ,        
        col.Def := '123456789';        //   
        col.FlagEnum := false;         //   ,    
        arr.ksAddArrayItem( -1, col );

        //   
        col.Header := 'str';            // o- 
        col.type_ := STRING_ATTR_TYPE;  //     - .
        col.Key := 0;                   //  ,        
        col.Def := 'string';            //   
        col.FlagEnum := false;          //   ,    
        arr.ksAddArrayItem( -1, col );

        //   
        col.Header := 'long';            // o- 
        col.type_ := LINT_ATTR_TYPE;     //     - .
        col.Key := 0;                    //  ,        
        col.Def := '1000000';            //   
        col.FlagEnum := false;           //   ,    
        arr.ksAddArrayItem( -1, col );
      end;

      nameFile := '';
      //   
      nameFile := kompas.ksChoiceFile( '*.lat', '', false );
      //   
      numbType := attr.ksCreateAttrType( type_,      //    
                                        nameFile ); //    
      if numbType > 1 then
        kompas.ksMessage( Format('numbType = %f', [numbType]) )
      else
        kompas.ksMessageBoxResult();  //     

      //    
      arr.ksDeleteArray();
    end;
  end;
end;

//-------------------------------------------------------------------------------
//
// ---
procedure DelTypeAttr();
var
	numb     : double;
	j        : integer;
	password : AnsiString;
	//  
	nameFile : AnsiString;
begin
	nameFile := kompas.ksChoiceFile( '*.lat', '', false );
  j := 1;
  while j > 0 do begin
    j := kompas.ksReadDouble( '   ', 1000., 0, 1e12, numb );
		if j > 0 then begin
			password := kompas.ksReadString( '   ', '' );
			if attr.ksDeleteAttrType(numb, nameFile, password) <= 0 then
				kompas.ksMessageBoxResult;  //     
		end;
	end;
end;

procedure ShowColumns( f1: bool; pCol: ksDynamicArray  ); forward;

//-------------------------------------------------------------------------------
//
// ---
procedure ShowCol( iCol: integer; f1: bool; par: ksColumnInfoParam );
var
  pCol : ksDynamicArray;
  s    : string;
begin
  if f1 then
    s := ''
  else
    s := '';

  //    
  kompas.ksMessage( Format( '%s i = %d header = %s type = %d def = %s flagEnum = %d',
                            [s, iCol, par.header, integer(par.type_), par.def, integer(par.flagEnum)] ) );
  if par.type_ = RECORD_ATTR_TYPE then
    begin // 
		pCol := ksDynamicArray( par.GetColumns() );
		if pCol <> nil then
    begin
			ShowColumns( true, pCol );
			pCol.ksDeleteArray();
    end;
  end;
end;

//-------------------------------------------------------------------------------
//
// ---
procedure ShowColumns( f1: bool; pCol: ksDynamicArray  );
var
  par : ksColumnInfoParam;
  i, n   : integer;
begin
  par := ksColumnInfoParam( kompas.GetParamStruct(ko_ColumnInfoParam) );
	if par <> nil then
    begin
		par.Init();
		n := pCol.ksGetArrayCount;

	  for i := 0 to n - 1 do
		  if pCol.ksGetArrayItem(i, par) = 0 then
			  kompas.ksMessageBoxResult  //     
			else
				ShowCol( i, f1, par )
  end;
end;

//--------------------------------------------------------------------------
//   
//--------------------------------------------------------------------------
procedure ShowTypeAttr();
var
  numb     : double;
	nameFile : AnsiString; //  
  type_    : ksAttributeTypeParam;
  pCol     : ksDynamicArray;
begin
	nameFile := kompas.ksChoiceFile( '*.lat', '', false );

	type_ := ksAttributeTypeParam( kompas.GetParamStruct(ko_AttributeType) );
	if type_ <> nil then begin
		type_.Init();
    numb := 1;
		while numb > 0 do begin
			numb := attr.ksChoiceAttrTypes( nameFile );
			if numb > 0 then begin
				if attr.ksGetAttrType(numb, nameFile, type_) = 0 then
					kompas.ksMessageBoxResult  //     
				else
        begin
					kompas.ksMessage( Format( 'key1 = %d key2 =%d key3 = %d key4 =%d',
                            [type_.key1, type_.key2, type_.key3, type_.key4] ) );
					kompas.ksMessage( Format( 'header = %s rowsCount = %d flagVisible = %d password = %s',
                            [type_.header, type_.rowsCount, integer(type_.flagVisible), type_.password] ) );
					pCol := ksDynamicArray( type_.GetColumns() );
					if pCol <> nil then begin
						ShowColumns( false, pCol );
						pCol.ksDeleteArray();
					end;
        end;
      end;
    end;
	end;
end;

//--------------------------------------------------------------------------
//   
//--------------------------------------------------------------------------
procedure ChangeType();
var
  numb, numbType : double;
	password : AnsiString;
	//  
	nameFile   : AnsiString;
  j, n       : integer;
  type_      : ksAttributeTypeParam;
  arr        : ksDynamicArray;
  par1, parN : ksColumnInfoParam;
begin
	nameFile := kompas.ksChoiceFile( '*.lat', '', false );
	type_ := ksAttributeTypeParam( kompas.GetParamStruct(ko_AttributeType) );
	if type_ <> nil then begin
		type_.Init();
    j := 1;
	  while j > 0 do begin
	    j := kompas.ksReadDouble( '   ', 1000., 0, 1e12, numb );
			if j > 0 then begin
				password := kompas.ksReadString( '   ', '' );
				//   
				if attr.ksGetAttrType(numb, StringToOleStr(nameFile), type_) = 0 then
					kompas.ksMessageBoxResult()  //     
				else begin
					type_.password := password;
					arr := ksDynamicArray( type_.GetColumns() );
					par1 := ksColumnInfoParam(kompas.GetParamStruct(ko_ColumnInfoParam) );
					parN := ksColumnInfoParam(kompas.GetParamStruct(ko_ColumnInfoParam) );
					if ( arr <> nil ) and ( par1 <> nil ) and ( parN <> nil ) then begin
						par1.Init();
						parN.Init();
						//  
						n := arr.ksGetArrayCount();
						//   
						arr.ksGetArrayItem( 0, par1 );
						//   
						arr.ksGetArrayItem( n-1, parN );
						//   
						arr.ksSetArrayItem( 0, parN );
						//   
						arr.ksSetArrayItem( n-1, par1 );

						//       
						numbType := attr.ksSetAttrType( numb, nameFile, type_, password );
						if numbType > 1 then
							kompas.ksMessage( Format('numbType = %f', [numbType]) )
						else
							kompas.ksMessageBoxResult;  //   -     

						arr.ksDeleteArray();
					end;
        end;
      end;
		end;
  end;
end;


//----------------------------------------------------------------------------
//  ,   FuncTypeAttr
//----------------------------------------------------------------------------
procedure NewAttr();
var
 attrPar : ksAttributeParam;
 usPar   : ksUserParam;
 fVisibl, colKeys, arr : ksDynamicArray;
 item    : ksLtVariant;
 info    : ksRequestInfo;
 x, y, numb  : double;
 j       : integer;
 pObj, pAttr : reference;
 fileName    : AnsiString;
begin

	attrPar := ksAttributeParam( kompas.GetParamStruct(ko_Attribute) );
	usPar := ksUserParam( kompas.GetParamStruct(ko_UserParam) );
	fVisibl := ksDynamicArray( kompas.GetDynamicArray(23) );
	colKeys := ksDynamicArray( kompas.GetDynamicArray(23) );
	if ( attrPar <> nil ) and ( usPar <> nil ) and ( fVisibl <> nil ) and ( colKeys <> nil ) then begin
		attrPar.Init();
		usPar.Init();
		attrPar.SetValues( usPar );
		attrPar.SetColumnKeys( colKeys );
		attrPar.SetFlagVisible( fVisibl );
		attrPar.Key1 := 1;
		attrPar.Key2 := 10;
		attrPar.Key3 := 100;
		attrPar.Password := '111';

		item := ksLtVariant( kompas.GetParamStruct(ko_LtVariant) );
		arr := ksDynamicArray( kompas.GetDynamicArray(23) );
		if ( item <> nil ) and ( arr <> nil ) then begin
			usPar.SetUserArray( arr );
			item.Init();
			item.DoubleVal := 987654321.0;
			arr.ksAddArrayItem( -1, item );
			item.Init();
			item.StrVal := 'qwerty';
			arr.ksAddArrayItem( -1, item );
			item.Init();
			item.LongVal := 999991;
			arr.ksAddArrayItem( -1, item );

			item.Init();
			item.UCharVal := 1;
			fVisibl.ksAddArrayItem( -1, item );
			fVisibl.ksAddArrayItem( -1, item );
			fVisibl.ksAddArrayItem( -1, item );
		end;

		info := ksRequestInfo( kompas.GetParamStruct(ko_RequestInfo) );
		if info <> nil then begin
			info.Init();
			info.Prompt := ' ';
			j := doc.ksCursor( info, x, y, nil );
			if j <> 0 then begin
				pObj := doc.ksFindObj( x, y, 1e6 );
				if doc.ksExistObj(pObj) > 0 then begin
					doc.ksLightObj( pObj, 1 );
					//   
					fileName := kompas.ksChoiceFile( '*.lat', '', false );
				  j := kompas.ksReadDouble( '   ', 1000., 0, 1e12, numb );
					if j > 0 then begin
						pAttr := attr.ksCreateAttr( pObj, attrPar, numb, fileName );
		        if pAttr = 0 then
			        kompas.ksMessageBoxResult();  //   -     
				  end;
					doc.ksLightObj( pObj, 0 );
        end;
	    end;
		end;
	end;
end;

//--------------------------------------------------------------------------
//       
//---------------------------------------------------------------------------
procedure DelObjAttr();
var
 info : ksRequestInfo;
 x, y : double;
 j    : integer;
 pObj, pAttr, obj : reference;
 iter : ksIterator;
 password : AnsiString;
begin
	info := ksRequestInfo( kompas.GetParamStruct(ko_RequestInfo) );
	if info <> nil then begin
		info.Init();
		info.Prompt := ' ';
    j := 1;
    while j > 0 do begin
			j := doc.ksCursor( info, x, y, nil );
			if j <> 0 then begin
				pObj := doc.ksFindObj( x, y, 1e6 );
				if doc.ksExistObj(pObj) > 0 then begin
					doc.ksLightObj( pObj, 1 );
	        //       
					iter := ksIterator( kompas.GetIterator() );
					if ( iter <> nil ) and iter.ksCreateAttrIterator(pObj, 0, 0, 0, 0, 0) then begin
		        //    
						pAttr := iter.ksMoveAttrIterator( 'F', obj );
						if pAttr > 0 then begin
							password := kompas.ksReadString('   ', '');
							if attr.ksDeleteAttr(pObj, pAttr, password) = 0 then
								kompas.ksMessageBoxResult();
            end
						else
							kompas.ksMessage( '  ' );

						doc.ksLightObj( pObj, 0 );
					end;
        end;
      end;
    end;
  end;
end;


//--------------------------------------------------------------------------
//    double_str_long
//---------------------------------------------------------------------------
procedure ReadObjAttr();
var
  res   : bool;
  usPar : ksUserParam;
  item  : ksLtVariant;
  arr   : ksDynamicArray;
  info  : ksRequestInfo;
  x, y, numb : double;
  j     : integer;
  pObj, pAttr, obj : reference;
  iter  : ksIterator;
  k1, k2, k3, k4 : integer;
begin
	res := false;
	usPar := ksUserParam( kompas.GetParamStruct(ko_UserParam) );
	if usPar <> nil then begin
		usPar.Init();
		item := ksLtVariant( kompas.GetParamStruct(ko_LtVariant) );
		arr := ksDynamicArray( kompas.GetDynamicArray(23) );
		if ( item <> nil ) and ( arr <> nil ) then begin
			usPar.SetUserArray( arr );
			item.Init();
			item.DoubleVal := 987654321.0;
			arr.ksAddArrayItem( -1, item );
			item.Init();
			item.StrVal := 'qwerty';
			arr.ksAddArrayItem( -1, item );
			item.Init();
			item.LongVal := 999991;
			arr.ksAddArrayItem( -1, item );
			res := true;
		end;
	end;

	if res then begin
    info := ksRequestInfo( kompas.GetParamStruct(ko_RequestInfo) );
		if info <> nil then begin
			info.Init();
			info.Prompt := ' ';
      j := 1;
      while j > 0 do begin
				j := doc.ksCursor( info, x, y, nil );
				if j <> 0 then begin
					pObj := doc.ksFindObj( x, y, 1e6 );
					if doc.ksExistObj( pObj ) > 0 then begin
						doc.ksLightObj( pObj, 1 );
		        //       
						iter := ksIterator( kompas.GetIterator() );
						if ( iter <> nil ) and iter.ksCreateAttrIterator(pObj, 0, 0, 0, 0, 0) then begin
				      //    
							pAttr := iter.ksMoveAttrIterator( 'F', obj );
							if pAttr > 0 then begin
				        kompas.ksMessage( '   ' );
						    attr.ksGetAttrKeysInfo( pAttr, k1, k2, k3, k4, numb );
							  kompas.ksMessage( Format('k1 = %d k2 = %d k3 = %d k4 = %d numb = %f',
                                  [k1, k2, k3, k4, numb] ) );

								kompas.ksMessage( ' ' );
								attr.ksGetAttrRow( pAttr, 0, nil, nil, usPar );

								kompas.ksMessage( '  ' );
								item := ksLtVariant( kompas.GetParamStruct(ko_LtVariant) );
								arr := ksDynamicArray( usPar.GetUserArray() );
								if ( item <> nil ) and ( arr <> nil ) then begin
									item.Init();
									item.DoubleVal := numb;
									arr.ksSetArrayItem( 0, item );
									item.Init();
									item.StrVal := '1234567\nasdfgh\nzxcvb';
									arr.ksSetArrayItem( 1, item );
									item.Init();
									item.LongVal := 888881;
									arr.ksSetArrayItem( 2, item );
									attr.ksSetAttrRow( pAttr, 0, nil, nil, usPar, '111' );
								end;
							end
							else
								kompas.ksMessage( '  ' );
						end;
						doc.ksLightObj( pObj, 0 );
					end;
				end;
      end;
		end;
	end;
end;

//--------------------------------------------------------------------------
//   
//---------------------------------------------------------------------------
procedure ShowObjAttr();
var
 info : ksRequestInfo;
 x, y : double;
 j    : integer;
 pObj : reference;
begin
	info := ksRequestInfo( kompas.GetParamStruct(ko_RequestInfo) );
	if info <> nil then begin
		info.Init();
		info.Prompt := ' ';
		j := 1;
		while j > 0 do begin
			j := doc.ksCursor( info, x, y, nil );
			if j <> 0 then begin
				pObj := doc.ksFindObj( x, y, 1e6 );
				if doc.ksExistObj(pObj) > 0 then begin
					doc.ksLightObj( pObj, 1 );
	        attr.ksChoiceAttr( pObj );
					doc.ksLightObj( pObj, 0 );
				end;
			end;
		end;
	end;
end;

//-------------------------------------------------------------------------------
// //  
// ---
procedure ShowLib();
var
  nameFile : AnsiString;
  numb     : double;
begin
	//   
	nameFile := kompas.ksChoiceFile( '*.lat', '', false );

  numb := attr.ksChoiceAttrTypes( nameFile );
  if ( numb > 1 ) then
    kompas.ksMessage( Format('numbType = %f', [numb]) );
end;


//-------------------------------------------------------------------------------
// //  
// ---
procedure ShowType();
var
  nameFile, password : AnsiString;
  numb : double;
  j : integer;
begin
	//   
	nameFile := kompas.ksChoiceFile( '*.lat', '', false );
  j := kompas.ksReadDouble( '   ', 1000., 0, 1e12, numb );
	if j > 0 then begin
		password := kompas.ksReadString( '   ', '' );
    attr.ksViewEditAttrType( nameFile, 2, numb, password );
  end;
end;


//---------------------------------------------------------------------------
//   ,     
// key1=10          
//---------------------------------------------------------------------------
procedure WalkFromObjWithAttr();
var
  info : ksRequestInfo;
  j : integer;
  x, y : double;
  pObj, pAttr, obj : reference;
  iter : ksIterator;
begin

	info := ksRequestInfo( kompas.GetParamStruct(ko_RequestInfo) );
	if info <> nil then begin
		info.Init();
		info.Prompt := ' ';
		j := 1;
		while j > 0 do begin
			j := doc.ksCursor( info, x, y, nil );
			if j <> 0 then begin
				pObj := doc.ksFindObj( x, y, 1e6 );
				if doc.ksExistObj( pObj ) > 0 then begin
		      //         10
          iter := ksIterator( kompas.GetIterator() );
					if ( iter <> nil ) and iter.ksCreateAttrIterator(pObj, 0, 0, 0, 0, 0) then begin
						doc.ksLightObj( pObj, 1 );
			      //    
						pAttr := iter.ksMoveAttrIterator( 'F', obj );
						if pAttr > 0 then
		          while pAttr > 0 do begin
				        attr.ksViewEditAttr( pAttr, 1, '' );
						    pAttr := iter.ksMoveAttrIterator( 'N', obj );
							end;

						doc.ksLightObj( pObj, 0 );
					end;
				end;
			end;
		end;
	end;
end;


//------------------------------------------------------------------------------
// LibraryEntry
//---
procedure LIBRARYENTRY( command: WORD ); pascal;
begin
  kompas := KompasObject( CreateKompasObject );

  if kompas <> nil then begin
    doc := ksDocument2D( kompas.ActiveDocument2D );
    attr := ksAttributeObject( kompas.GetAttributeObject );
    if ( doc <> nil ) and ( attr <> nil ) then begin
      case command of
        1  : FuncAttrType; //   
        2  : DelTypeAttr;  //   
        3  : ShowTypeAttr; //   
        4  : ChangeType;   //   
        5  : NewAttr;      //   ,   FuncTypeAttr
        6  : DelObjAttr;   //       
        7  : ReadObjAttr;  //    double_str_long
        8  : ShowObjAttr;  //   
        9  : ShowLib;      //  
        10 : ShowType;     //  
        11 : WalkFromObjWithAttr; //  
      end;

      kompas.ksMessageBoxResult;
      doc := nil;
    end;
    kompas := nil;
  end;
end;


end.
